diff --git a/examples/xml/reference/reference_example.py b/examples/xml/reference/reference_example.py
new file mode 100644
index 0000000..47c91f9
--- /dev/null
+++ b/examples/xml/reference/reference_example.py
@@ -0,0 +1,7 @@
+"""
+Application data type examples
+"""
+import autosar.xml.element as ar_element
+
+ref = ar_element.ExclusiveAreaRef("/Areas/Area1")
+print(str(ref))
diff --git a/src/autosar/xml/element.py b/src/autosar/xml/element.py
index ba36d1a..90fb562 100644
--- a/src/autosar/xml/element.py
+++ b/src/autosar/xml/element.py
@@ -530,9 +530,16 @@ class BaseRef(ARObject, abc.ABC):
def __init__(self,
value: str,
- dest: ar_enum.IdentifiableSubTypes) -> None:
+ dest: ar_enum.IdentifiableSubTypes = None) -> None:
self.value = value
self.dest: ar_enum.IdentifiableSubTypes = None
+ if dest is None:
+ if len(self._accepted_subtypes()) == 1:
+ dest = list(self._accepted_subtypes())[0]
+ else:
+ msg_part1 = "Value of dest cannot be None. Accepted values are: "
+ msg_part2 = ",".join([str(x) for x in sorted(list(self._accepted_subtypes()))])
+ raise ValueError(msg_part1 + msg_part2)
if dest in self._accepted_subtypes():
self.dest = dest
else:
@@ -999,6 +1006,26 @@ def _accepted_subtypes(self) -> set[ar_enum.IdentifiableSubTypes]:
"""Acceptable values for dest"""
return {ar_enum.IdentifiableSubTypes.SWC_IMPLEMENTATION}
+
+class ExclusiveAreaRef(BaseRef):
+ """
+ EXCLUSIVE-AREA--SUBTYPES-ENUM
+ """
+
+ def _accepted_subtypes(self) -> set[ar_enum.IdentifiableSubTypes]:
+ """Acceptable values for dest"""
+ return {ar_enum.IdentifiableSubTypes.EXCLUSIVE_AREA}
+
+
+class ExclusiveAreaNestingOrderRef(BaseRef):
+ """
+ AR:EXCLUSIVE-AREA-NESTING-ORDER--SUBTYPES-ENUM
+ """
+
+ def _accepted_subtypes(self) -> set[ar_enum.IdentifiableSubTypes]:
+ """Acceptable values for dest"""
+ return {ar_enum.IdentifiableSubTypes.EXCLUSIVE_AREA_NESTING_ORDER}
+
# --- Documentation Elements
@@ -2437,8 +2464,7 @@ def __init__(self,
class ImplementationProps(Referrable):
"""
- Complex type AR:IMPLEMENTATION-PROPS
- Type: Abstract
+ Group AR:IMPLEMENTATION-PROPS
"""
def __init__(self,
@@ -6016,3 +6042,173 @@ def ref(self) -> SwcImplementationRef | None:
if ref_str is None:
return None
return SwcImplementationRef(ref_str)
+
+
+class ExecutableEntityActivationReason(ImplementationProps):
+ """
+ Complex type AR:EXECUTABLE-ENTITY-ACTIVATION-REASON
+ Tag variants: 'EXECUTABLE-ENTITY-ACTIVATION-REASON'
+ """
+
+ def __init__(self,
+ name: str,
+ bit_position: int | None = None,
+ **kwargs) -> None:
+ super().__init__(name, **kwargs)
+ self.bit_position: int | None = None
+ self._assign_optional_positive_int("bit_position", bit_position)
+
+
+class ExclusiveAreaRefConditional(ARObject):
+ """
+ Complex type AR:EXCLUSIVE-AREA-REF-CONDITIONAL
+ Tag variants: 'EXCLUSIVE-AREA-REF-CONDITIONAL'
+ """
+
+ def __init__(self,
+ exclusive_area_ref: ExclusiveAreaRef | str | None = None) -> None:
+ self.exclusive_area_ref: ExclusiveAreaRef | None = None # .EXCLUSIVE-AREA-REF
+ self._assign_optional("exclusive_area_ref", exclusive_area_ref, ExclusiveAreaRef)
+
+
+ActivationReasonArgumentType = ExecutableEntityActivationReason | list[ExecutableEntityActivationReason] | None
+CanEnterLeaveArgumentType = Union[ExclusiveAreaRefConditional,
+ list[ExclusiveAreaRefConditional],
+ ExclusiveAreaRef,
+ list[ExclusiveAreaRef],
+ str,
+ None]
+
+ExclusiveAreaNestingOrderArgumentType = ExclusiveAreaNestingOrderRef | list[ExclusiveAreaNestingOrderRef] | None
+RunsInsidesArgumentType = Union[ExclusiveAreaRefConditional,
+ list[ExclusiveAreaRefConditional],
+ ExclusiveAreaRef,
+ list[ExclusiveAreaRef],
+ str,
+ None]
+
+ExclusiveAreaElementArgumentType = ExclusiveAreaRefConditional | ExclusiveAreaRef | str
+
+
+class ExecutableEntity(Identifiable):
+ """
+ Group AR:EXECUTABLE-ENTITY
+ """
+
+ def __init__(self,
+ name: str,
+ activation_reasons: ActivationReasonArgumentType = None,
+ can_enter_leave: CanEnterLeaveArgumentType = None,
+ exclusive_area_nesting_order: ExclusiveAreaNestingOrderArgumentType = None,
+ minimum_start_interval: float | None = None,
+ reentrancy_level: ar_enum.ReentrancyLevel | None = None,
+ runs_insides: RunsInsidesArgumentType = None,
+ sw_addr_method: str | SwAddrMethodRef | None = None,
+ **kwargs) -> None:
+ super().__init__(name, **kwargs)
+ self.activation_reasons: list[ExecutableEntityActivationReason] = [] # .ACTIVATION-REASONS
+ # .CAN-ENTERS or CAN-ENTER-EXCLUSIVE-AREA-REFS depending on schema version
+ self.can_enter_leave: list[ExclusiveAreaRefConditional] = []
+ self.exclusive_area_nesting_order: list[ExclusiveAreaNestingOrderRef] = [] # .EXCLUSIVE-AREA-NESTING-ORDER-REFS
+ self.minimum_start_interval: float | None = None # .MINIMUM-START-INTERVAL
+ self.reentrancy_level: ar_enum.ReentrancyLevel | None = None # .REENTRANCY-LEVEL
+ # .RUNS-INSIDES or .RUNS-INSIDE-EXCLUSIVE-AREA-REFS depending on schema version
+ self.runs_insides: list[ExclusiveAreaRefConditional] = []
+ self.sw_addr_method: str | SwAddrMethodRef | None = None # .SW-ADDR-METHOD-REF
+
+ if activation_reasons is not None:
+ if isinstance(activation_reasons, list):
+ for activation_reason in activation_reasons:
+ self.append_activation_reason(activation_reason)
+ else:
+ self.append_activation_reason(activation_reasons)
+ if can_enter_leave is not None:
+ if isinstance(can_enter_leave, list):
+ for elem in can_enter_leave:
+ self.append_can_enter_leave(elem)
+ else:
+ self.append_can_enter_leave(can_enter_leave)
+ if exclusive_area_nesting_order is not None:
+ if isinstance(exclusive_area_nesting_order, ExclusiveAreaNestingOrderRef):
+ self.append_exclusive_area_nesting_order(exclusive_area_nesting_order)
+ elif isinstance(exclusive_area_nesting_order, list):
+ for elem in exclusive_area_nesting_order:
+ self.append_exclusive_area_nesting_order(elem)
+ self._assign_optional("minimum_start_interval", minimum_start_interval, float)
+ self._assign_optional("reentrancy_level", reentrancy_level, ar_enum.ReentrancyLevel)
+ if runs_insides is not None:
+ if isinstance(runs_insides, list):
+ for elem in runs_insides:
+ self.append_runs_insides(elem)
+ else:
+ self.append_runs_insides(runs_insides)
+ self._assign_optional('sw_addr_method', sw_addr_method, SwAddrMethodRef)
+
+ def append_activation_reason(self, activation_reason: ExecutableEntityActivationReason) -> None:
+ """
+ Appends activation_reason to internal list of activation reasons
+ """
+ if isinstance(activation_reason, ExecutableEntityActivationReason):
+ self.activation_reasons.append(activation_reason)
+ else:
+ raise TypeError("activation_reason must be of type ExecutableEntityActivationReason")
+
+ def append_can_enter_leave(self, value: ExclusiveAreaElementArgumentType) -> None:
+ """
+ Tthe executable entity can enter/leave the referenced exclusive area through explicit API calls
+ """
+ if isinstance(value, ExclusiveAreaRefConditional):
+ self.can_enter_leave.append(value)
+ elif isinstance(value, (ExclusiveAreaRef, str)):
+ self.can_enter_leave.append(ExclusiveAreaRefConditional(value))
+ else:
+ raise TypeError("value: Invalid type. Expected one of ExclusiveAreaRefConditional, ExclusiveAreaRef, str.")
+
+ def append_exclusive_area_nesting_order(self, exclusive_area_nesting_order: ExclusiveAreaNestingOrderRef) -> None:
+ """
+ Appends exclusive area reference to internal can_enter_leave list
+ """
+ if isinstance(exclusive_area_nesting_order, ExclusiveAreaNestingOrderRef):
+ self.exclusive_area_nesting_order.append(exclusive_area_nesting_order)
+ else:
+ raise TypeError("exclusive_area_nesting_order must be of type ExclusiveAreaRefConditional")
+
+ def append_runs_insides(self, value: ExclusiveAreaElementArgumentType) -> None:
+ """
+ The executable entity runs completely inside the referenced exclusive area
+ """
+ if isinstance(value, ExclusiveAreaRefConditional):
+ self.runs_insides.append(value)
+ elif isinstance(value, (ExclusiveAreaRef, str)):
+ self.runs_insides.append(ExclusiveAreaRefConditional(value))
+ else:
+ raise TypeError("value: Invalid type. Expected one of ExclusiveAreaRefConditional, ExclusiveAreaRef, str.")
+
+
+class RunnableEntity(ExecutableEntity):
+ """
+ Complex type AR:RUNNABLE-ENTITY
+ Tag variants: 'RUNNABLE-ENTITY'
+ Only implements base class features for now.
+ """
+
+ def __init__(self,
+ name: str,
+ **kwargs) -> None:
+ super().__init__(name, **kwargs)
+
+
+# --- Future stuff
+
+
+class RModeInAtomicSwcInstanceRef(ARObject):
+ """
+ Complex type AR:R-MODE-IN-ATOMIC-SWC-INSTANCE-REF
+ Tag variants: 'DISABLED-MODE-IREF' | 'MODE-IREF'
+ """
+
+
+class RTEEvent(Identifiable):
+ """
+ Group AR:RTE-EVENT
+ """
diff --git a/src/autosar/xml/enumeration.py b/src/autosar/xml/enumeration.py
index 0a49547..45f4903 100644
--- a/src/autosar/xml/enumeration.py
+++ b/src/autosar/xml/enumeration.py
@@ -219,28 +219,31 @@ class IdentifiableSubTypes(Enum):
DATA_CONSTR = 25
DATA_PROTOTYPE = 26
E2E_PROFILE_COMPATIBILITY_PROPS = 27
- IMPLEMENTATION_DATA_TYPE = 28
- IMPLEMENTATION_DATA_TYPE_ELEMENT = 29
- MODE_DECLARATION = 30
- MODE_DECLARATION_GROUP = 31
- MODE_DECLARATION_GROUP_PROTOTYPE = 32
- MODE_SWITCH_INTERFACE = 33
- NV_DATA_INTERFACE = 34
- P_PORT_PROTOTYPE = 35
- PARAMETER_INTERFACE = 36
- PARAMETER_DATA_PROTOTYPE = 37
- PHYSICAL_DIMENSION = 38
- PORT_PROTOTYPE = 39
- PR_PORT_PROTOTYPE = 40
- R_PORT_PROTOTYPE = 41
- SENDER_RECEIVER_INTERFACE = 42
- SW_ADDR_METHOD = 43
- SW_BASE_TYPE = 44
- SW_COMPONENT_PROTOTYPE = 45
- SWC_IMPLEMENTATION = 46
- SWC_INTERNAL_BEHAVIOR = 47
- UNIT = 48
- VARIABLE_DATA_PROTOTYPE = 49
+ EXCLUSIVE_AREA = 28
+ EXCLUSIVE_AREA_NESTING_ORDER = 29
+ IMPLEMENTATION_DATA_TYPE = 30
+ IMPLEMENTATION_DATA_TYPE_ELEMENT = 31
+ MODE_DECLARATION = 32
+ MODE_DECLARATION_GROUP = 33
+ MODE_DECLARATION_GROUP_PROTOTYPE = 34
+ MODE_SWITCH_INTERFACE = 35
+ NV_DATA_INTERFACE = 36
+ P_PORT_PROTOTYPE = 37
+ PARAMETER_INTERFACE = 38
+ PARAMETER_DATA_PROTOTYPE = 39
+ PHYSICAL_DIMENSION = 40
+ PORT_PROTOTYPE = 41
+ PR_PORT_PROTOTYPE = 42
+ R_PORT_PROTOTYPE = 43
+ RUNNABLE_ENTITY = 44
+ SENDER_RECEIVER_INTERFACE = 45
+ SW_ADDR_METHOD = 46
+ SW_BASE_TYPE = 47
+ SW_COMPONENT_PROTOTYPE = 48
+ SWC_IMPLEMENTATION = 49
+ SWC_INTERNAL_BEHAVIOR = 50
+ UNIT = 51
+ VARIABLE_DATA_PROTOTYPE = 52
class IntervalType(Enum):
@@ -465,6 +468,16 @@ class PageWide(Enum):
PGWIDE = 1
+class ReentrancyLevel(Enum):
+ """
+ AR:REENTRANCY-LEVEL-ENUM--SIMPLE
+ """
+
+ MULTICORE_REENTRANT = 0
+ NON_REENTRANT = 1
+ SINGLE_CORE_REENTRANT = 2
+
+
class ScaleConstraintValidity(Enum):
"""
AR:SCALE-CONSTR-VALIDITY-ENUM--SIMPLE
@@ -720,6 +733,8 @@ class VersionedTextValue:
"CONSTANT-SPECIFICATION": IdentifiableSubTypes.CONSTANT_SPECIFICATION,
"DATA-CONSTR": IdentifiableSubTypes.DATA_CONSTR,
"E-2-E-PROFILE-COMPATIBILITY-PROPS": IdentifiableSubTypes.E2E_PROFILE_COMPATIBILITY_PROPS,
+ "EXCLUSIVE-AREA": IdentifiableSubTypes.EXCLUSIVE_AREA,
+ "EXCLUSIVE-AREA-NESTING-ORDER": IdentifiableSubTypes.EXCLUSIVE_AREA_NESTING_ORDER,
"IMPLEMENTATION-DATA-TYPE": IdentifiableSubTypes.IMPLEMENTATION_DATA_TYPE,
"IMPLEMENTATION-DATA-TYPE-ELEMENT": IdentifiableSubTypes.IMPLEMENTATION_DATA_TYPE_ELEMENT,
"MODE-DECLARATION": IdentifiableSubTypes.MODE_DECLARATION,
@@ -734,6 +749,7 @@ class VersionedTextValue:
"PORT-PROTOTYPE": IdentifiableSubTypes.PORT_PROTOTYPE,
"PR-PORT-PROTOTYPE": IdentifiableSubTypes.PR_PORT_PROTOTYPE,
"R-PORT-PROTOTYPE": IdentifiableSubTypes.R_PORT_PROTOTYPE,
+ "RUNNABLE-ENTITY": IdentifiableSubTypes.RUNNABLE_ENTITY,
"SENDER-RECEIVER-INTERFACE": IdentifiableSubTypes.SENDER_RECEIVER_INTERFACE,
"SW-ADDR-METHOD": IdentifiableSubTypes.SW_ADDR_METHOD,
"SW-BASE-TYPE": IdentifiableSubTypes.SW_BASE_TYPE,
@@ -911,6 +927,11 @@ class VersionedTextValue:
"NO-PGWIDE": PageWide.NO_PGWIDE,
"PGWIDE": PageWide.PGWIDE,
},
+ "ReentrancyLevel": {
+ "MULTICORE-REENTRANT": ReentrancyLevel.MULTICORE_REENTRANT,
+ "NON-REENTRANT": ReentrancyLevel.NON_REENTRANT,
+ "SINGLE-CORE-REENTRANT": ReentrancyLevel.SINGLE_CORE_REENTRANT
+ },
"ScaleConstraintValidity": {
"NOT-AVAILABLE": ScaleConstraintValidity.NOT_AVAILABLE,
"NOT-DEFINED": ScaleConstraintValidity.NOT_DEFINED,
@@ -1077,28 +1098,31 @@ def xml_to_enum(enum_type_name: str, xml_text: str, schema_version: int = ar_bas
"DATA-CONSTR", # 25
"DATA-PROTOTYPE", # 26
"E-2-E-PROFILE-COMPATIBILITY-PROPS", # 27
- "IMPLEMENTATION-DATA-TYPE", # 28
- "IMPLEMENTATION-DATA-TYPE-ELEMENT", # 29
- "MODE-DECLARATION", # 30
- "MODE-DECLARATION-GROUP", # 31
- "MODE-DECLARATION-GROUP-PROTOTYPE", # 32
- "MODE-SWITCH-INTERFACE", # 33
- "NV-DATA-INTERFACE", # 34
- "P-PORT-PROTOTYPE", # 35
- "PARAMETER-INTERFACE", # 36
- "PARAMETER-DATA-PROTOTYPE", # 37
- "PHYSICAL-DIMENSION", # 38
- "PORT-PROTOTYPE", # 39
- "PR-PORT-PROTOTYPE", # 40
- "R-PORT-PROTOTYPE", # 41
- "SENDER-RECEIVER-INTERFACE", # 42
- "SW-ADDR-METHOD", # 43
- "SW-BASE-TYPE", # 44
- "SW-COMPONENT-PROTOTYPE", # 45
- "SWC-IMPLEMENTATION", # 46
- "SWC-INTERNAL-BEHAVIOR", # 47
- "UNIT", # 48
- "VARIABLE-DATA-PROTOTYPE", # 49
+ "EXCLUSIVE-AREA", # 28
+ "EXCLUSIVE-AREA-NESTING-ORDER", # 29
+ "IMPLEMENTATION-DATA-TYPE", # 30
+ "IMPLEMENTATION-DATA-TYPE-ELEMENT", # 31
+ "MODE-DECLARATION", # 32
+ "MODE-DECLARATION-GROUP", # 33
+ "MODE-DECLARATION-GROUP-PROTOTYPE", # 34
+ "MODE-SWITCH-INTERFACE", # 35
+ "NV-DATA-INTERFACE", # 36
+ "P-PORT-PROTOTYPE", # 37
+ "PARAMETER-INTERFACE", # 38
+ "PARAMETER-DATA-PROTOTYPE", # 39
+ "PHYSICAL-DIMENSION", # 40
+ "PORT-PROTOTYPE", # 41
+ "PR-PORT-PROTOTYPE", # 42
+ "R-PORT-PROTOTYPE", # 43
+ "RUNNABLE-ENTITY", # 44
+ "SENDER-RECEIVER-INTERFACE", # 45
+ "SW-ADDR-METHOD", # 46
+ "SW-BASE-TYPE", # 47
+ "SW-COMPONENT-PROTOTYPE", # 48
+ "SWC-IMPLEMENTATION", # 49
+ "SWC-INTERNAL-BEHAVIOR", # 50
+ "UNIT", # 51
+ "VARIABLE-DATA-PROTOTYPE", # 52
],
"IntervalType": [
"CLOSED", # 0
@@ -1268,6 +1292,11 @@ def xml_to_enum(enum_type_name: str, xml_text: str, schema_version: int = ar_bas
"NO-PGWIDE", # 0
"PGWIDE", # 1
],
+ "ReentrancyLevel": [
+ "MULTICORE-REENTRANT", # 0
+ "NON-REENTRANT", # 1
+ "SINGLE-CORE-REENTRANT" # 2
+ ],
"ScaleConstraintValidity": [
"NOT-AVAILABLE", # 0
"NOT-DEFINED", # 1
diff --git a/src/autosar/xml/reader.py b/src/autosar/xml/reader.py
index 0b23fcd..64b1b22 100644
--- a/src/autosar/xml/reader.py
+++ b/src/autosar/xml/reader.py
@@ -264,7 +264,10 @@ def __init__(self,
'AUTOSAR-VARIABLE-IREF': self._read_variable_in_atomic_swc_type_instance_ref,
'ACCESSED-VARIABLE': self._read_autosar_variable_ref,
'VARIABLE-ACCESS': self._read_variable_access,
+ 'EXECUTABLE-ENTITY-ACTIVATION-REASON': self._read_executable_entity_activation_reason,
+ 'EXCLUSIVE-AREA-REF-CONDITIONAL': self._read_exclusive_area_ref_conditional,
'SWC-INTERNAL-BEHAVIOR': self._read_swc_internal_behavior,
+ 'RUNNABLE-ENTITY': self._read_runnable_entity,
}
self.switcher_all = {}
self.switcher_all.update(self.switcher_collectable)
@@ -1657,8 +1660,7 @@ def _read_sw_data_def_props_content(self, child_elements: ChildElementMap, data:
data['annotations'] = self._read_annotations(xml_child)
xml_child = child_elements.get('SW-ADDR-METHOD-REF')
if xml_child is not None:
- data['sw_addr_method_ref'] = self._read_sw_addr_method_ref(
- xml_child)
+ data['sw_addr_method_ref'] = self._read_sw_addr_method_ref(xml_child)
xml_child = child_elements.get('SW-ALIGNMENT')
if xml_child is not None:
try:
@@ -2527,7 +2529,7 @@ def _read_data_prototype_ref(self,
xml_elem: ElementTree.Element
) -> ar_element.DataPrototypeRef:
"""
- Reads references to References to DATA-PROTOTYPE--SUBTYPES-ENUM
+ Reads references to DATA-PROTOTYPE--SUBTYPES-ENUM
"""
data = {}
self._read_base_ref_attributes(xml_elem.attrib, data)
@@ -2538,7 +2540,7 @@ def _read_port_interface_ref(self,
xml_elem: ElementTree.Element
) -> ar_element.PortInterfaceRef:
"""
- Reads references to References to PORT-INTERFACE--SUBTYPES-ENUM
+ Reads references to PORT-INTERFACE--SUBTYPES-ENUM
"""
data = {}
self._read_base_ref_attributes(xml_elem.attrib, data)
@@ -2549,7 +2551,7 @@ def _read_sw_component_type_ref(self,
xml_elem: ElementTree.Element
) -> ar_element.SwComponentTypeRef:
"""
- Reads references to References to SW-COMPONENT-TYPE--SUBTYPES-ENUM
+ Reads references to SW-COMPONENT-TYPE--SUBTYPES-ENUM
"""
data = {}
self._read_base_ref_attributes(xml_elem.attrib, data)
@@ -2560,7 +2562,7 @@ def _read_sw_component_prototype_ref(self,
xml_elem: ElementTree.Element
) -> ar_element.SwComponentPrototypeRef:
"""
- Reads reference to references to SW-COMPONENT-PROTOTYPE--SUBTYPES-ENUM
+ Reads reference to SW-COMPONENT-PROTOTYPE--SUBTYPES-ENUM
"""
data = {}
self._read_base_ref_attributes(xml_elem.attrib, data)
@@ -2573,7 +2575,7 @@ def _read_swc_internal_behavior_ref(self,
xml_elem: ElementTree.Element
) -> ar_element.SwcInternalBehaviorRef:
"""
- Reads reference to references to SWC-INTERNAL-BEHAVIOR--SUBTYPES-ENUM
+ Reads reference to SWC-INTERNAL-BEHAVIOR--SUBTYPES-ENUM
"""
data = {}
self._read_base_ref_attributes(xml_elem.attrib, data)
@@ -2582,6 +2584,28 @@ def _read_swc_internal_behavior_ref(self,
raise ar_exception.ParseError(msg)
return ar_element.SwcInternalBehaviorRef(xml_elem.text)
+ def _read_exclusive_area_ref(self,
+ xml_elem: ElementTree.Element
+ ) -> ar_element.ExclusiveAreaRef:
+ """
+ Reads references to AR:EXCLUSIVE-AREA--SUBTYPES-ENUM
+ """
+ data = {}
+ self._read_base_ref_attributes(xml_elem.attrib, data)
+ dest_enum = ar_enum.xml_to_enum('IdentifiableSubTypes', data['dest'], self.schema_version)
+ return ar_element.ExclusiveAreaRef(xml_elem.text, dest_enum)
+
+ def _read_exclusive_area_nesting_order_ref(self,
+ xml_elem: ElementTree.Element
+ ) -> ar_element.ExclusiveAreaNestingOrderRef:
+ """
+ Reads references to AR:EXCLUSIVE-AREA-NESTING-ORDER--SUBTYPES-ENUM
+ """
+ data = {}
+ self._read_base_ref_attributes(xml_elem.attrib, data)
+ dest_enum = ar_enum.xml_to_enum('IdentifiableSubTypes', data['dest'], self.schema_version)
+ return ar_element.ExclusiveAreaNestingOrderRef(xml_elem.text, dest_enum)
+
# --- Constant and value specifications
def _read_text_value_specification(self,
@@ -4345,6 +4369,139 @@ def _read_autosar_variable_ref_group(self, child_elements: ChildElementMap, data
if xml_child is not None:
data["local_variable_ref"] = self._read_variable_data_prototype_ref(xml_child)
+ def _read_executable_entity_activation_reason(self,
+ xml_element: ElementTree.Element
+ ) -> ar_element.ExecutableEntityActivationReason:
+ """
+ Reads complex type AR:EXECUTABLE-ENTITY-ACTIVATION-REASON
+ Tag variants: 'EXECUTABLE-ENTITY-ACTIVATION-REASON'
+ """
+ data = {}
+ child_elements = ChildElementMap(xml_element)
+ self._read_referrable(child_elements, data)
+ self._read_implementation_props(child_elements, data)
+ xml_child = child_elements.get("BIT-POSITION")
+ if xml_child is not None:
+ data["bit_position"] = ar_element.PositiveIntegerValue(xml_child.text).value
+ self._report_unprocessed_elements(child_elements)
+ return ar_element.ExecutableEntityActivationReason(**data)
+
+ def _read_exclusive_area_ref_conditional(self,
+ xml_element: ElementTree.Element
+ ) -> ar_element.ExclusiveAreaRefConditional:
+ """
+ Reads complex type AR:EXCLUSIVE-AREA-REF-CONDITIONAL
+ Tag variants: 'EXCLUSIVE-AREA-REF-CONDITIONAL'
+ """
+ data = {}
+ child_elements = ChildElementMap(xml_element)
+ xml_child = child_elements.get("EXCLUSIVE-AREA-REF")
+ if xml_child is not None:
+ data["exclusive_area_ref"] = self._read_exclusive_area_ref(xml_child)
+ child_elements.skip("VARIATION-POINT") # Not supported
+ self._report_unprocessed_elements(child_elements)
+ return ar_element.ExclusiveAreaRefConditional(**data)
+
+ def _read_executable_entity(self, child_elements: ChildElementMap, data: dict) -> None:
+ """
+ Reads group AR:EXECUTABLE-ENTITY
+ """
+ xml_child = child_elements.get("ACTIVATION-REASONS")
+ if xml_child is not None:
+ activation_reasons = []
+ for xml_grand_child in xml_child.findall("./EXECUTABLE-ENTITY-ACTIVATION-REASON"):
+ activation_reasons.append(self._read_executable_entity_activation_reason(xml_grand_child))
+ data["activation_reasons"] = activation_reasons
+ if not isinstance(self.schema_version, int):
+ raise RuntimeError("Schema version is not set, unable to proceed")
+ if self.schema_version < 50:
+ xml_child = child_elements.get("CAN-ENTER-EXCLUSIVE-AREA-REFS")
+ if xml_child is not None:
+ can_enter_leave = []
+ for xml_grand_child in xml_child.findall("./CAN-ENTER-EXCLUSIVE-AREA-REF"):
+ # The class constructor will automatically upgrade these references to
+ # ExclusiveAreaRefConditional elements.
+ can_enter_leave.append(self._read_exclusive_area_ref(xml_grand_child))
+ data["can_enter_leave"] = can_enter_leave
+ else:
+ xml_child = child_elements.get("CAN-ENTERS")
+ if xml_child is not None:
+ can_enter_leave = []
+ for xml_grand_child in xml_child.findall("./EXCLUSIVE-AREA-REF-CONDITIONAL"):
+ can_enter_leave.append(self._read_exclusive_area_ref_conditional(xml_grand_child))
+ data["can_enter_leave"] = can_enter_leave
+ xml_child = child_elements.get("EXCLUSIVE-AREA-NESTING-ORDER-REFS")
+ if xml_child is not None:
+ exclusive_area_nesting_order = []
+ for xml_grand_child in xml_child.findall("./EXCLUSIVE-AREA-NESTING-ORDER-REF"):
+ exclusive_area_nesting_order.append(self._read_exclusive_area_nesting_order_ref(xml_grand_child))
+ data["exclusive_area_nesting_order"] = exclusive_area_nesting_order
+ xml_child = child_elements.get("MINIMUM-START-INTERVAL")
+ if xml_child is not None:
+ data["minimum_start_interval"] = self._read_number(xml_child.text)
+ xml_child = child_elements.get("REENTRANCY-LEVEL")
+ if xml_child is not None:
+ data["reentrancy_level"] = ar_enum.xml_to_enum("ReentrancyLevel", xml_child.text)
+ if self.schema_version < 50:
+ xml_child = child_elements.get("RUNS-INSIDE-EXCLUSIVE-AREA-REFS")
+ if xml_child is not None:
+ runs_insides = []
+ for xml_grand_child in xml_child.findall("./RUNS-INSIDE-EXCLUSIVE-AREA-REF"):
+ # The class constructor will automatically upgrade these references to
+ # ExclusiveAreaRefConditional elements.
+ runs_insides.append(self._read_exclusive_area_ref(xml_grand_child))
+ data["runs_insides"] = runs_insides
+ else:
+ xml_child = child_elements.get("RUNS-INSIDES")
+ if xml_child is not None:
+ runs_insides = []
+ for xml_grand_child in xml_child.findall("./EXCLUSIVE-AREA-REF-CONDITIONAL"):
+ runs_insides.append(self._read_exclusive_area_ref_conditional(xml_grand_child))
+ data["runs_insides"] = runs_insides
+ xml_child = child_elements.get('SW-ADDR-METHOD-REF')
+ if xml_child is not None:
+ data['sw_addr_method'] = self._read_sw_addr_method_ref(xml_child)
+
+ def _read_runnable_entity(self, xml_element: ElementTree.Element) -> ar_element.RunnableEntity:
+ """
+ Reads complex type AR:RUNNABLE-ENTITY
+ Tag variants: 'RUNNABLE-ENTITY'
+ """
+ data = {}
+ child_elements = ChildElementMap(xml_element)
+ self._read_referrable(child_elements, data)
+ self._read_multi_language_referrable(child_elements, data)
+ self._read_identifiable(child_elements, xml_element.attrib, data)
+ self._read_executable_entity(child_elements, data)
+ self._read_runnable_entity_group(child_elements, data)
+ self._report_unprocessed_elements(child_elements)
+ return ar_element.RunnableEntity(**data)
+
+ def _read_runnable_entity_group(self, child_elements: ChildElementMap, data: dict) -> None:
+ """
+ Reads group AR:RUNNABLE-ENTITY
+ These elements will be implemented in the next releae
+ """
+ child_elements.skip("ARGUMENTS")
+ child_elements.skip("ASYNCHRONOUS-SERVER-CALL-RESULT-POINTS")
+ child_elements.skip("CAN-BE-INVOKED-CONCURRENTLY")
+ child_elements.skip("DATA-READ-ACCESSS")
+ child_elements.skip("DATA-RECEIVE-POINT-BY-ARGUMENTS")
+ child_elements.skip("DATA-RECEIVE-POINT-BY-VALUES")
+ child_elements.skip("DATA-SEND-POINTS")
+ child_elements.skip("DATA-WRITE-ACCESSS")
+ child_elements.skip("EXTERNAL-TRIGGERING-POINTS")
+ child_elements.skip("INTERNAL-TRIGGERING-POINTS")
+ child_elements.skip("MODE-ACCESS-POINTS")
+ child_elements.skip("MODE-SWITCH-POINTS")
+ child_elements.skip("PARAMETER-ACCESSS")
+ child_elements.skip("READ-LOCAL-VARIABLES")
+ child_elements.skip("SERVER-CALL-POINTS")
+ child_elements.skip("SYMBOL")
+ child_elements.skip("WAIT-POINTS")
+ child_elements.skip("WRITTEN-LOCAL-VARIABLES")
+ child_elements.skip("VARIATION-POINT")
+
def _read_swc_internal_behavior(self, xml_element: ElementTree.Element) -> ar_element.SwcInternalBehavior:
"""
Reads complex type AR:SWC-INTERNAL-BEHAVIOR
diff --git a/src/autosar/xml/writer.py b/src/autosar/xml/writer.py
index b9294c1..948290a 100644
--- a/src/autosar/xml/writer.py
+++ b/src/autosar/xml/writer.py
@@ -7,6 +7,7 @@
import sys
import math
import decimal
+import autosar.base as ar_base
import autosar.xml.document as ar_document
import autosar.xml.element as ar_element
import autosar.xml.enumeration as ar_enum
@@ -181,8 +182,11 @@ class Writer(_XMLWriter):
ARXML writer class
"""
- def __init__(self) -> None:
+ def __init__(self,
+ schema_version: int = ar_base.DEFAULT_SCHEMA_VERSION) -> None:
super().__init__(indentation_step=2)
+ self.schema_version = schema_version
+
# Elements found in AR:PACKAGE
self.switcher_collectable = {
# Package
@@ -332,6 +336,9 @@ def __init__(self) -> None:
'AutosarVariableRef': self._write_autosar_variable_ref,
'VariableAccess': self._write_variable_access,
'SwcInternalBehavior': self._write_swc_internal_behavior,
+ 'ExecutableEntityActivationReason': self._write_executable_entity_activation_reason,
+ 'ExclusiveAreaRefConditional': self._write_exclusive_area_ref_conditional,
+ 'RunnableEntity': self._write_runnable_entity,
}
self.switcher_all = {} # All concrete elements (used for unit testing)
@@ -439,6 +446,7 @@ def _write_admin_data(self, data: dict) -> None:
# AUTOSAR Document
def _write_document(self, document: ar_document.Document, skip_root_attr: bool = False):
+ self.schema_version = document.schema_version
self._add_line('')
if skip_root_attr:
self._add_child("AUTOSAR")
@@ -1971,8 +1979,7 @@ def _write_sw_base_type_ref(self, elem: ar_element.SwBaseTypeRef) -> None:
def _write_sw_addr_method_ref(self, elem: ar_element.SwAddrMethodRef) -> None:
"""
- Writes complex type AR:SW-ADDR-METHOD-REF
- Type: Concrete
+ Writes references to AR:SW-ADDR-METHOD--SUBTYPES-ENUM
Tag variants: 'SW-ADDR-METHOD-REF'
"""
assert isinstance(elem, ar_element.SwAddrMethodRef)
@@ -2230,6 +2237,28 @@ def _write_sw_component_prototype_ref(self,
self._collect_base_ref_attr(elem, attr)
self._add_content(tag, elem.value, attr)
+ def _write_exclusive_area_ref(self,
+ elem: ar_element.ExclusiveAreaRef,
+ tag: str) -> None:
+ """
+ Writes references to EXCLUSIVE-AREA--SUBTYPES-ENUM
+ """
+ assert isinstance(elem, ar_element.ExclusiveAreaRef)
+ attr: TupleList = []
+ self._collect_base_ref_attr(elem, attr)
+ self._add_content(tag, elem.value, attr)
+
+ def _write_exclusive_area_nesting_order_ref(self,
+ elem: ar_element.ExclusiveAreaNestingOrderRef,
+ tag: str) -> None:
+ """
+ Writes references to EXCLUSIVE-AREA-NESTING-ORDER--SUBTYPES-ENUM
+ """
+ assert isinstance(elem, ar_element.ExclusiveAreaNestingOrderRef)
+ attr: TupleList = []
+ self._collect_base_ref_attr(elem, attr)
+ self._add_content(tag, elem.value, attr)
+
def _write_swc_internal_behavior_ref(self,
elem: ar_element.SwcInternalBehaviorRef,
tag: str) -> None:
@@ -3717,6 +3746,7 @@ def _write_variable_access(self, elem: ar_element.VariableAccess, tag: str) -> N
Writes complex type AR:VARIABLE-ACCESS
Tag variants: 'REPLACE-WITH' | 'VARIABLE-ACCESS'
"""
+ assert isinstance(elem, ar_element.VariableAccess)
self._add_child(tag)
self._write_referrable(elem)
self._write_multilanguage_referrable(elem)
@@ -3727,6 +3757,107 @@ def _write_variable_access(self, elem: ar_element.VariableAccess, tag: str) -> N
self._add_content("SCOPE", ar_enum.enum_to_xml(elem.scope))
self._leave_child()
+ def _write_executable_entity_activation_reason(self,
+ elem: ar_element.ExecutableEntityActivationReason) -> None:
+ """
+ Writes complex type AR:EXECUTABLE-ENTITY-ACTIVATION-REASON
+ Tag variants: 'EXECUTABLE-ENTITY-ACTIVATION-REASON'
+ """
+ assert isinstance(elem, ar_element.ExecutableEntityActivationReason)
+ self._add_child("EXECUTABLE-ENTITY-ACTIVATION-REASON")
+ self._write_referrable(elem)
+ self._write_implementation_props(elem)
+ if elem.bit_position is not None:
+ self._add_content("BIT-POSITION", str(elem.bit_position))
+ self._leave_child()
+
+ def _write_exclusive_area_ref_conditional(self,
+ elem: ar_element.ExclusiveAreaRefConditional) -> None:
+ """
+ Writes complex type AR:EXCLUSIVE-AREA-REF-CONDITIONAL
+ Tag variants: 'EXCLUSIVE-AREA-REF-CONDITIONAL'
+ """
+ assert isinstance(elem, ar_element.ExclusiveAreaRefConditional)
+ tag = "EXCLUSIVE-AREA-REF-CONDITIONAL"
+ if elem.is_empty:
+ self._add_content(tag)
+ else:
+ self._add_child(tag)
+ if elem.exclusive_area_ref is not None:
+ self._write_exclusive_area_ref(elem.exclusive_area_ref, "EXCLUSIVE-AREA-REF")
+ self._leave_child()
+
+ def _write_executable_entity(self, elem: ar_element.ExecutableEntity) -> None:
+ """
+ Writes group AR:EXECUTABLE-ENTITY
+ """
+ if elem.activation_reasons:
+ self._add_child("ACTIVATION-REASONS")
+ for activation_reason in elem.activation_reasons:
+ self._write_executable_entity_activation_reason(activation_reason)
+ self._leave_child()
+ if elem.can_enter_leave:
+ if not isinstance(self.schema_version, int):
+ raise RuntimeError("Schema version is not set, unable to proceed")
+ if self.schema_version < 50:
+ self._add_child("CAN-ENTER-EXCLUSIVE-AREA-REFS")
+ for child_elem in elem.can_enter_leave:
+ self._write_exclusive_area_ref(child_elem.exclusive_area_ref,
+ "CAN-ENTER-EXCLUSIVE-AREA-REF")
+ self._leave_child()
+ else:
+ self._add_child("CAN-ENTERS")
+ for child_elem in elem.can_enter_leave:
+ self._write_exclusive_area_ref_conditional(child_elem)
+ self._leave_child()
+ if elem.exclusive_area_nesting_order:
+ self._add_child("EXCLUSIVE-AREA-NESTING-ORDER-REFS")
+ for nesting_order_ref in elem.exclusive_area_nesting_order:
+ self._write_exclusive_area_nesting_order_ref(nesting_order_ref,
+ "EXCLUSIVE-AREA-NESTING-ORDER-REF")
+ self._leave_child()
+ if elem.minimum_start_interval is not None:
+ self._add_content("MINIMUM-START-INTERVAL", self._format_number(elem.minimum_start_interval))
+ if elem.reentrancy_level is not None:
+ self._add_content("REENTRANCY-LEVEL", ar_enum.enum_to_xml(elem.reentrancy_level))
+ if elem.runs_insides:
+ if not isinstance(self.schema_version, int):
+ raise RuntimeError("Schema version is not set, unable to proceed")
+ if self.schema_version < 50:
+ self._add_child("RUNS-INSIDE-EXCLUSIVE-AREA-REFS")
+ for child_elem in elem.runs_insides:
+ self._write_exclusive_area_ref(child_elem.exclusive_area_ref,
+ "RUNS-INSIDE-EXCLUSIVE-AREA-REF")
+ self._leave_child()
+ else:
+ self._add_child("RUNS-INSIDES")
+ for child_elem in elem.runs_insides:
+ self._write_exclusive_area_ref_conditional(child_elem)
+ self._leave_child()
+ if elem.sw_addr_method is not None:
+ self._write_sw_addr_method_ref(elem.sw_addr_method)
+
+ def _write_runnable_entity(self, elem: ar_element.RunnableEntity) -> None:
+ """
+ Writes complex type AR:RUNNABLE-ENTITY
+ Tag variants: 'RUNNABLE-ENTITY'
+
+ This is in early stage, most will be implemented later
+ """
+ self._add_child("RUNNABLE-ENTITY")
+ self._write_referrable(elem)
+ self._write_multilanguage_referrable(elem)
+ self._write_identifiable(elem)
+ self._write_executable_entity(elem)
+ self._leave_child()
+
+ def _write_runnable_entity_group(self, elem: ar_element.RunnableEntity) -> None:
+ """
+ Writes group type AR:RUNNABLE-ENTITY
+
+ This is just a placeholder. Will be implemented later
+ """
+
def _write_swc_internal_behavior(self, elem: ar_element.SwcInternalBehavior) -> None:
"""
Writes complex type AR:SWC-INTERNAL-BEHAVIOR
diff --git a/tests/xml/test_swc_internal_behavior.py b/tests/xml/test_swc_internal_behavior.py
index b494b84..b630936 100644
--- a/tests/xml/test_swc_internal_behavior.py
+++ b/tests/xml/test_swc_internal_behavior.py
@@ -226,5 +226,490 @@ def test_local_variable_ref(self):
self.assertIsInstance(elem.local_variable_ref, ar_element.VariableDataPrototypeRef)
+class TestExecutableEntityActivationReason(unittest.TestCase):
+
+ def test_read_write_name_only(self):
+ writer = autosar.xml.Writer()
+ element = ar_element.ExecutableEntityActivationReason('MyName')
+ xml = '''
+ MyName
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ExecutableEntityActivationReason = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ExecutableEntityActivationReason)
+ self.assertEqual(elem.name, 'MyName')
+ self.assertEqual(elem.short_name, 'MyName')
+
+ def test_read_write_bit_position(self):
+ writer = autosar.xml.Writer()
+ element = ar_element.ExecutableEntityActivationReason('MyName', bit_position=0)
+ xml = '''
+ MyName
+ 0
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ExecutableEntityActivationReason = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ExecutableEntityActivationReason)
+ self.assertEqual(elem.name, 'MyName')
+ self.assertEqual(elem.bit_position, 0)
+
+
+class TestExclusiveAreaRefConditional(unittest.TestCase):
+
+ def test_empty(self):
+ element = ar_element.ExclusiveAreaRefConditional()
+ writer = autosar.xml.Writer()
+ xml = writer.write_str_elem(element)
+ self.assertEqual(xml, '')
+ reader = autosar.xml.Reader()
+ elem: ar_element.ExclusiveAreaRefConditional = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ExclusiveAreaRefConditional)
+
+ def test_exclusive_area_ref_from_str(self):
+ ref_str = "/ExclusiveAreas/AreaName"
+ element = ar_element.ExclusiveAreaRefConditional(ref_str)
+ writer = autosar.xml.Writer()
+ xml = f'''
+ {ref_str}
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ExclusiveAreaRefConditional = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ExclusiveAreaRefConditional)
+ self.assertEqual(str(elem.exclusive_area_ref), ref_str)
+
+
+class TestExecutableEntity(unittest.TestCase):
+ """
+ ExecutableEntity is a base class. Use RunnableEntity
+ for unit testing.
+ """
+
+ def test_name_only(self):
+ writer = autosar.xml.Writer()
+ element = ar_element.RunnableEntity('MyName')
+ xml = '''
+ MyName
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(elem.name, 'MyName')
+ self.assertEqual(elem.short_name, 'MyName')
+
+ def test_activation_reasons_from_element(self):
+ writer = autosar.xml.Writer()
+ reason = ar_element.ExecutableEntityActivationReason("MyReason", 1, symbol="MySymbol")
+ element = ar_element.RunnableEntity('MyName', activation_reasons=reason)
+ xml = '''
+ MyName
+
+
+ MyReason
+ MySymbol
+ 1
+
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(len(elem.activation_reasons), 1)
+ activation_reason = elem.activation_reasons[0]
+ self.assertIsInstance(activation_reason, ar_element.ExecutableEntityActivationReason)
+ self.assertEqual(activation_reason.name, 'MyReason')
+
+ def test_activation_reasons_from_list(self):
+ writer = autosar.xml.Writer()
+ reasons = [ar_element.ExecutableEntityActivationReason("MyReason1", 0, symbol="MySymbol1"),
+ ar_element.ExecutableEntityActivationReason("MyReason2", 1, symbol="MySymbol2")]
+ element = ar_element.RunnableEntity('MyName', activation_reasons=reasons)
+ xml = '''
+ MyName
+
+
+ MyReason1
+ MySymbol1
+ 0
+
+
+ MyReason2
+ MySymbol2
+ 1
+
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(len(elem.activation_reasons), 2)
+ activation_reason = elem.activation_reasons[0]
+ self.assertIsInstance(activation_reason, ar_element.ExecutableEntityActivationReason)
+ self.assertEqual(activation_reason.name, 'MyReason1')
+ activation_reason = elem.activation_reasons[1]
+ self.assertIsInstance(activation_reason, ar_element.ExecutableEntityActivationReason)
+ self.assertEqual(activation_reason.name, 'MyReason2')
+
+ def test_can_enters_from_element(self):
+ """
+ CAN-ENTERS is used for XML schema version >= 50
+ """
+ ref_str = "/MyPackage/MySwc/MyExclusiveArea"
+ writer = autosar.xml.Writer()
+ exclusive_area_cond = ar_element.ExclusiveAreaRefConditional(ref_str)
+ element = ar_element.RunnableEntity('MyName', can_enter_leave=exclusive_area_cond)
+ xml = f'''
+ MyName
+
+
+ {ref_str}
+
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(len(elem.can_enter_leave), 1)
+ conditional: ar_element.ExclusiveAreaRefConditional = elem.can_enter_leave[0]
+ self.assertIsInstance(conditional, ar_element.ExclusiveAreaRefConditional)
+ self.assertEqual(str(conditional.exclusive_area_ref), ref_str)
+
+ def test_can_enters_from_list(self):
+ ref_str1 = "/MyPackage/MySwc/MyExclusiveArea1"
+ ref_str2 = "/MyPackage/MySwc/MyExclusiveArea2"
+ writer = autosar.xml.Writer()
+ exclusive_area_cond = [ar_element.ExclusiveAreaRefConditional(ref_str1),
+ ar_element.ExclusiveAreaRefConditional(ref_str2)]
+ element = ar_element.RunnableEntity('MyName', can_enter_leave=exclusive_area_cond)
+ xml = f'''
+ MyName
+
+
+ {ref_str1}
+
+
+ {ref_str2}
+
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(len(elem.can_enter_leave), 2)
+ conditional: ar_element.ExclusiveAreaRefConditional = elem.can_enter_leave[0]
+ self.assertIsInstance(conditional, ar_element.ExclusiveAreaRefConditional)
+ self.assertEqual(str(conditional.exclusive_area_ref), ref_str1)
+ conditional: ar_element.ExclusiveAreaRefConditional = elem.can_enter_leave[1]
+ self.assertIsInstance(conditional, ar_element.ExclusiveAreaRefConditional)
+ self.assertEqual(str(conditional.exclusive_area_ref), ref_str2)
+
+ def test_can_enter_exclusive_area_from_element(self):
+ """
+ CAN-ENTER-EXCLUSIVE-AREA-REFS is used for XML schema version < 50
+ """
+ ref_str = "/MyPackage/MySwc/MyExclusiveArea"
+ writer = autosar.xml.Writer(schema_version=49)
+ exclusive_area_cond = ar_element.ExclusiveAreaRefConditional(ref_str)
+ element = ar_element.RunnableEntity('MyName', can_enter_leave=exclusive_area_cond)
+ xml = f'''
+ MyName
+
+ {ref_str}
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader(schema_version=49)
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(len(elem.can_enter_leave), 1)
+ conditional: ar_element.ExclusiveAreaRefConditional = elem.can_enter_leave[0]
+ self.assertIsInstance(conditional, ar_element.ExclusiveAreaRefConditional)
+ self.assertEqual(str(conditional.exclusive_area_ref), ref_str)
+
+ def test_can_enter_exclusive_area_from_list(self):
+ ref_str1 = "/MyPackage/MySwc/MyExclusiveArea1"
+ ref_str2 = "/MyPackage/MySwc/MyExclusiveArea2"
+ writer = autosar.xml.Writer(schema_version=49)
+ exclusive_area_cond = [ar_element.ExclusiveAreaRefConditional(ref_str1),
+ ar_element.ExclusiveAreaRefConditional(ref_str2)]
+ element = ar_element.RunnableEntity('MyName', can_enter_leave=exclusive_area_cond)
+ xml = f'''
+ MyName
+
+ {ref_str1}
+ {ref_str2}
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader(schema_version=49)
+ # During XML reading, elements of type ExclusiveAreaRef are automatically wrapped
+ # inside the newer ExclusiveAreaRefConditional element
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(len(elem.can_enter_leave), 2)
+ conditional: ar_element.ExclusiveAreaRefConditional = elem.can_enter_leave[0]
+ self.assertIsInstance(conditional, ar_element.ExclusiveAreaRefConditional)
+ self.assertEqual(str(conditional.exclusive_area_ref), ref_str1)
+ conditional: ar_element.ExclusiveAreaRefConditional = elem.can_enter_leave[1]
+ self.assertIsInstance(conditional, ar_element.ExclusiveAreaRefConditional)
+ self.assertEqual(str(conditional.exclusive_area_ref), ref_str2)
+
+ def test_can_enter_create_directly_from_reference_string(self):
+ ref_str = "/MyPackage/MySwc/MyExclusiveArea"
+ writer = autosar.xml.Writer()
+ exclusive_area_cond = ar_element.ExclusiveAreaRefConditional(ref_str)
+ element = ar_element.RunnableEntity('MyName', can_enter_leave=exclusive_area_cond)
+ xml = f'''
+ MyName
+
+
+ {ref_str}
+
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+
+ def test_can_enter_create_from_list_of_reference_strings(self):
+ ref_str1 = "/MyPackage/MySwc/MyExclusiveArea1"
+ ref_str2 = "/MyPackage/MySwc/MyExclusiveArea2"
+ writer = autosar.xml.Writer()
+ element = ar_element.RunnableEntity('MyName', can_enter_leave=[ref_str1, ref_str2])
+ xml = f'''
+ MyName
+
+
+ {ref_str1}
+
+
+ {ref_str2}
+
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+
+ def test_exclusive_area_nesting_order_refs_from_element(self):
+ ref_str = "/MyPackage/MySwc/MyExclusiveAreaNestingOrder"
+ writer = autosar.xml.Writer()
+ exclusive_area_nesting_order = ar_element.ExclusiveAreaNestingOrderRef(ref_str)
+ element = ar_element.RunnableEntity('MyName', exclusive_area_nesting_order=exclusive_area_nesting_order)
+ xml = f'''
+ MyName
+
+ {ref_str}
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(len(elem.exclusive_area_nesting_order), 1)
+ nesting_order: ar_element.ExclusiveAreaNestingOrderRef = elem.exclusive_area_nesting_order[0]
+ self.assertIsInstance(nesting_order, ar_element.ExclusiveAreaNestingOrderRef)
+ self.assertEqual(str(nesting_order), ref_str)
+
+ def test_exclusive_area_nesting_order_refs_from_list(self):
+ ref_str1 = "/MyPackage/MySwc/MyExclusiveAreaNestingOrder1"
+ ref_str2 = "/MyPackage/MySwc/MyExclusiveAreaNestingOrder1"
+ writer = autosar.xml.Writer()
+ exclusive_area_nesting_order = [ar_element.ExclusiveAreaNestingOrderRef(ref_str1),
+ ar_element.ExclusiveAreaNestingOrderRef(ref_str1)]
+ element = ar_element.RunnableEntity('MyName', exclusive_area_nesting_order=exclusive_area_nesting_order)
+ xml = f'''
+ MyName
+
+ {ref_str1}
+ {ref_str2}
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(len(elem.exclusive_area_nesting_order), 2)
+ nesting_order: ar_element.ExclusiveAreaNestingOrderRef = elem.exclusive_area_nesting_order[0]
+ self.assertIsInstance(nesting_order, ar_element.ExclusiveAreaNestingOrderRef)
+ self.assertEqual(str(nesting_order), ref_str1)
+ nesting_order = elem.exclusive_area_nesting_order[1]
+ self.assertIsInstance(nesting_order, ar_element.ExclusiveAreaNestingOrderRef)
+ self.assertEqual(str(nesting_order), ref_str2)
+
+ def test_minimum_start_interval_100ms(self):
+ writer = autosar.xml.Writer()
+ element = ar_element.RunnableEntity('MyName', minimum_start_interval=0.1)
+ xml = '''
+ MyName
+ 0.1
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertAlmostEqual(elem.minimum_start_interval, 0.1)
+
+ def test_minimum_start_interval_2s(self):
+ writer = autosar.xml.Writer()
+ element = ar_element.RunnableEntity('MyName', minimum_start_interval=2)
+ xml = '''
+ MyName
+ 2
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(elem.minimum_start_interval, 2)
+
+ def test_reentrancy_level(self):
+ writer = autosar.xml.Writer()
+ element = ar_element.RunnableEntity('MyName',
+ reentrancy_level=ar_enum.ReentrancyLevel.SINGLE_CORE_REENTRANT)
+ xml = '''
+ MyName
+ SINGLE-CORE-REENTRANT
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(elem.reentrancy_level, ar_enum.ReentrancyLevel.SINGLE_CORE_REENTRANT)
+
+ def test_runs_insides_from_element(self):
+ """
+ RUNS-INSIDES is used for XML schema version >= 50
+ """
+ ref_str = "/MyPackage/MySwc/MyExclusiveArea"
+ writer = autosar.xml.Writer()
+ exclusive_area_cond = ar_element.ExclusiveAreaRefConditional(ref_str)
+ element = ar_element.RunnableEntity('MyName', runs_insides=exclusive_area_cond)
+ xml = f'''
+ MyName
+
+
+ {ref_str}
+
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(len(elem.runs_insides), 1)
+ conditional: ar_element.ExclusiveAreaRefConditional = elem.runs_insides[0]
+ self.assertIsInstance(conditional, ar_element.ExclusiveAreaRefConditional)
+ self.assertEqual(str(conditional.exclusive_area_ref), ref_str)
+
+ def test_runs_insides_from_list(self):
+ ref_str1 = "/MyPackage/MySwc/MyExclusiveArea1"
+ ref_str2 = "/MyPackage/MySwc/MyExclusiveArea2"
+ writer = autosar.xml.Writer()
+ exclusive_area_cond = [ar_element.ExclusiveAreaRefConditional(ref_str1),
+ ar_element.ExclusiveAreaRefConditional(ref_str2)]
+ element = ar_element.RunnableEntity('MyName', runs_insides=exclusive_area_cond)
+ xml = f'''
+ MyName
+
+
+ {ref_str1}
+
+
+ {ref_str2}
+
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(len(elem.runs_insides), 2)
+ conditional: ar_element.ExclusiveAreaRefConditional = elem.runs_insides[0]
+ self.assertIsInstance(conditional, ar_element.ExclusiveAreaRefConditional)
+ self.assertEqual(str(conditional.exclusive_area_ref), ref_str1)
+ conditional: ar_element.ExclusiveAreaRefConditional = elem.runs_insides[1]
+ self.assertIsInstance(conditional, ar_element.ExclusiveAreaRefConditional)
+ self.assertEqual(str(conditional.exclusive_area_ref), ref_str2)
+
+ def test_runs_inside_exclusive_area_from_element(self):
+ """
+ RUNS-INSIDE-EXCLUSIVE-AREA-REFS is used for XML schema version < 50
+ """
+ ref_str = "/MyPackage/MySwc/MyExclusiveArea"
+ writer = autosar.xml.Writer(schema_version=49)
+ exclusive_area_cond = ar_element.ExclusiveAreaRefConditional(ref_str)
+ element = ar_element.RunnableEntity('MyName', runs_insides=exclusive_area_cond)
+ xml = f'''
+ MyName
+
+ {ref_str}
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader(schema_version=49)
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(len(elem.runs_insides), 1)
+ conditional: ar_element.ExclusiveAreaRefConditional = elem.runs_insides[0]
+ self.assertIsInstance(conditional, ar_element.ExclusiveAreaRefConditional)
+ self.assertEqual(str(conditional.exclusive_area_ref), ref_str)
+
+ def test_run_insides_exclusive_area_from_list(self):
+ ref_str1 = "/MyPackage/MySwc/MyExclusiveArea1"
+ ref_str2 = "/MyPackage/MySwc/MyExclusiveArea2"
+ writer = autosar.xml.Writer(schema_version=49)
+ exclusive_area_cond = [ar_element.ExclusiveAreaRefConditional(ref_str1),
+ ar_element.ExclusiveAreaRefConditional(ref_str2)]
+ element = ar_element.RunnableEntity('MyName', runs_insides=exclusive_area_cond)
+ xml = f'''
+ MyName
+
+ {ref_str1}
+ {ref_str2}
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader(schema_version=49)
+ # During XML reading, elements of type ExclusiveAreaRef are automatically wrapped
+ # inside the newer ExclusiveAreaRefConditional element
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ self.assertEqual(len(elem.runs_insides), 2)
+ conditional: ar_element.ExclusiveAreaRefConditional = elem.runs_insides[0]
+ self.assertIsInstance(conditional, ar_element.ExclusiveAreaRefConditional)
+ self.assertEqual(str(conditional.exclusive_area_ref), ref_str1)
+ conditional: ar_element.ExclusiveAreaRefConditional = elem.runs_insides[1]
+ self.assertIsInstance(conditional, ar_element.ExclusiveAreaRefConditional)
+ self.assertEqual(str(conditional.exclusive_area_ref), ref_str2)
+
+ def test_sw_addr_method_from_element(self):
+ ref_str = '/SwAddrMethods/DEFAULT'
+ writer = autosar.xml.Writer()
+ element = ar_element.RunnableEntity('MyName',
+ sw_addr_method=ar_element.SwAddrMethodRef(ref_str))
+ xml = f'''
+ MyName
+ {ref_str}
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.RunnableEntity = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.RunnableEntity)
+ ref = elem.sw_addr_method
+ self.assertEqual(ref.value, '/SwAddrMethods/DEFAULT')
+ self.assertEqual(ref.dest, ar_enum.IdentifiableSubTypes.SW_ADDR_METHOD)
+
+ def test_create_sw_addr_method_from_string(self):
+ ref_str = '/SwAddrMethods/DEFAULT'
+ element = ar_element.RunnableEntity('MyName', sw_addr_method=ref_str)
+ ref = element.sw_addr_method
+ self.assertEqual(ref.value, '/SwAddrMethods/DEFAULT')
+ self.assertEqual(ref.dest, ar_enum.IdentifiableSubTypes.SW_ADDR_METHOD)
+
+
if __name__ == '__main__':
unittest.main()