odxtools 5.2.6__py3-none-any.whl → 5.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. odxtools/basicstructure.py +2 -2
  2. odxtools/cli/browse.py +18 -20
  3. odxtools/cli/dummy_sub_parser.py +3 -3
  4. odxtools/cli/main.py +1 -1
  5. odxtools/compumethods/compuscale.py +1 -2
  6. odxtools/compumethods/createanycompumethod.py +0 -1
  7. odxtools/compumethods/identicalcompumethod.py +0 -2
  8. odxtools/compumethods/limit.py +1 -1
  9. odxtools/compumethods/linearcompumethod.py +1 -1
  10. odxtools/compumethods/scalelinearcompumethod.py +0 -1
  11. odxtools/compumethods/tabintpcompumethod.py +0 -1
  12. odxtools/determinenumberofitems.py +18 -0
  13. odxtools/diagdatadictionaryspec.py +14 -4
  14. odxtools/diaglayer.py +54 -59
  15. odxtools/dynamiclengthfield.py +59 -0
  16. odxtools/element.py +2 -4
  17. odxtools/endofpdufield.py +6 -77
  18. odxtools/field.py +94 -0
  19. odxtools/isotp_state_machine.py +20 -24
  20. odxtools/matchingparameter.py +1 -1
  21. odxtools/multiplexer.py +6 -18
  22. odxtools/multiplexercase.py +22 -6
  23. odxtools/multiplexerdefaultcase.py +10 -2
  24. odxtools/multiplexerswitchkey.py +8 -43
  25. odxtools/odxlink.py +8 -4
  26. odxtools/odxtypes.py +1 -1
  27. odxtools/parameters/codedconstparameter.py +4 -2
  28. odxtools/parameters/dynamicparameter.py +6 -4
  29. odxtools/parameters/lengthkeyparameter.py +8 -3
  30. odxtools/parameters/matchingrequestparameter.py +5 -3
  31. odxtools/parameters/nrcconstparameter.py +4 -2
  32. odxtools/parameters/parameter.py +21 -6
  33. odxtools/parameters/parameterwithdop.py +6 -1
  34. odxtools/parameters/physicalconstantparameter.py +4 -2
  35. odxtools/parameters/reservedparameter.py +4 -2
  36. odxtools/parameters/systemparameter.py +5 -3
  37. odxtools/parameters/tableentryparameter.py +5 -3
  38. odxtools/parameters/tablekeyparameter.py +8 -4
  39. odxtools/parameters/tablestructparameter.py +4 -2
  40. odxtools/parameters/valueparameter.py +5 -3
  41. odxtools/positioneddataobjectproperty.py +74 -0
  42. odxtools/progcode.py +2 -3
  43. odxtools/tablerow.py +1 -2
  44. odxtools/templates/macros/printAudience.xml.jinja2 +3 -9
  45. odxtools/templates/macros/printCompanyData.xml.jinja2 +4 -27
  46. odxtools/templates/macros/printComparam.xml.jinja2 +4 -18
  47. odxtools/templates/macros/printDOP.xml.jinja2 +3 -9
  48. odxtools/templates/macros/printDynamicLengthField.xml.jinja2 +22 -0
  49. odxtools/templates/macros/printElementID.xml.jinja2 +6 -6
  50. odxtools/templates/macros/printEndOfPdu.xml.jinja2 +3 -2
  51. odxtools/templates/macros/printEnvData.xml.jinja2 +2 -2
  52. odxtools/templates/macros/printEnvDataDesc.xml.jinja2 +3 -2
  53. odxtools/templates/macros/printFunctionalClass.xml.jinja2 +3 -9
  54. odxtools/templates/macros/printMux.xml.jinja2 +13 -6
  55. odxtools/templates/macros/printParam.xml.jinja2 +2 -7
  56. odxtools/templates/macros/printRequest.xml.jinja2 +2 -9
  57. odxtools/templates/macros/printResponse.xml.jinja2 +2 -9
  58. odxtools/templates/macros/printService.xml.jinja2 +2 -9
  59. odxtools/templates/macros/printSpecialData.xml.jinja2 +1 -1
  60. odxtools/templates/macros/printState.xml.jinja2 +3 -9
  61. odxtools/templates/macros/printStateChart.xml.jinja2 +2 -9
  62. odxtools/templates/macros/printStateTransition.xml.jinja2 +3 -9
  63. odxtools/templates/macros/printStructure.xml.jinja2 +2 -4
  64. odxtools/templates/macros/printTable.xml.jinja2 +2 -7
  65. odxtools/templates/macros/printUnitSpec.xml.jinja2 +3 -3
  66. odxtools/templates/macros/printVariant.xml.jinja2 +10 -9
  67. odxtools/version.py +4 -2
  68. {odxtools-5.2.6.dist-info → odxtools-5.3.1.dist-info}/METADATA +70 -13
  69. {odxtools-5.2.6.dist-info → odxtools-5.3.1.dist-info}/RECORD +73 -68
  70. {odxtools-5.2.6.dist-info → odxtools-5.3.1.dist-info}/LICENSE +0 -0
  71. {odxtools-5.2.6.dist-info → odxtools-5.3.1.dist-info}/WHEEL +0 -0
  72. {odxtools-5.2.6.dist-info → odxtools-5.3.1.dist-info}/entry_points.txt +0 -0
  73. {odxtools-5.2.6.dist-info → odxtools-5.3.1.dist-info}/top_level.txt +0 -0
@@ -10,7 +10,7 @@ from .parameter import ParameterType
10
10
  from .parameterwithdop import ParameterWithDOP
11
11
 
12
12
  if TYPE_CHECKING:
13
- from diaglayer import DiagLayer
13
+ from ..diaglayer import DiagLayer
14
14
 
15
15
 
16
16
  @dataclass
@@ -43,10 +43,15 @@ class LengthKeyParameter(ParameterWithDOP):
43
43
  def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
44
44
  super()._resolve_snrefs(diag_layer)
45
45
 
46
- def is_required(self):
46
+ @property
47
+ def is_required(self) -> bool:
47
48
  return False
48
49
 
49
- def is_optional(self):
50
+ @property
51
+ def is_settable(self) -> bool:
52
+ # length keys can be explicitly set, but they do not need to
53
+ # be because they can be implicitly determined by the length
54
+ # of the corresponding field
50
55
  return True
51
56
 
52
57
  def get_coded_value_as_bytes(self, encode_state: EncodeState) -> bytes:
@@ -20,10 +20,12 @@ class MatchingRequestParameter(Parameter):
20
20
  def bit_length(self):
21
21
  return 8 * self.byte_length
22
22
 
23
- def is_required(self):
24
- return True
23
+ @property
24
+ def is_required(self) -> bool:
25
+ return False
25
26
 
26
- def is_optional(self):
27
+ @property
28
+ def is_settable(self) -> bool:
27
29
  return False
28
30
 
29
31
  def get_coded_value(self, request_value=None):
@@ -55,10 +55,12 @@ class NrcConstParameter(Parameter):
55
55
  def internal_data_type(self) -> DataType:
56
56
  return self.diag_coded_type.base_data_type
57
57
 
58
- def is_required(self):
58
+ @property
59
+ def is_required(self) -> bool:
59
60
  return False
60
61
 
61
- def is_optional(self):
62
+ @property
63
+ def is_settable(self) -> bool:
62
64
  return False
63
65
 
64
66
  def get_coded_value(self):
@@ -62,13 +62,28 @@ class Parameter(NamedElement, abc.ABC):
62
62
  def bit_length(self) -> Optional[int]:
63
63
  return None
64
64
 
65
- @abc.abstractmethod
66
- def is_required(self):
67
- pass
65
+ @property
66
+ def is_required(self) -> bool:
67
+ """True if the parameter must be explicitly specified when
68
+ encoding a message.
68
69
 
69
- @abc.abstractmethod
70
- def is_optional(self):
71
- pass
70
+ Required parameters are always settable, and parameters which
71
+ have a default value are settable but not required to be
72
+ specified.
73
+
74
+ """
75
+ raise NotImplementedError
76
+
77
+ @property
78
+ def is_settable(self) -> bool:
79
+ """True if the parameter can be specified when encoding a
80
+ message.
81
+
82
+ Required parameters are always settable, and parameters which
83
+ have a default value are settable but not required to be
84
+ specified.
85
+ """
86
+ raise NotImplementedError
72
87
 
73
88
  @abc.abstractmethod
74
89
  def get_coded_value(self):
@@ -46,7 +46,12 @@ class ParameterWithDOP(Parameter):
46
46
  if self.dop_snref:
47
47
  spec = diag_layer.diag_data_dictionary_spec
48
48
  self._dop = (
49
- spec.data_object_props.get(self.dop_snref) or spec.structures.get(self.dop_snref))
49
+ spec.end_of_pdu_fields.get(self.dop_snref) or
50
+ spec.dynamic_length_fields.get(self.dop_snref) or
51
+ spec.data_object_props.get(self.dop_snref) or spec.structures.get(self.dop_snref) or
52
+ spec.muxs.get(self.dop_snref) or spec.dtc_dops.get(self.dop_snref) or
53
+ spec.muxs.get(self.dop_snref) or spec.env_data_descs.get(self.dop_snref) or
54
+ spec.env_datas.get(self.dop_snref))
50
55
 
51
56
  @property
52
57
  def dop(self) -> Optional[DopBase]:
@@ -44,10 +44,12 @@ class PhysicalConstantParameter(ParameterWithDOP):
44
44
  def physical_constant_value(self) -> ParameterValue:
45
45
  return self._physical_constant_value
46
46
 
47
- def is_required(self):
47
+ @property
48
+ def is_required(self) -> bool:
48
49
  return False
49
50
 
50
- def is_optional(self):
51
+ @property
52
+ def is_settable(self) -> bool:
51
53
  return False
52
54
 
53
55
  def get_coded_value(self):
@@ -15,10 +15,12 @@ class ReservedParameter(Parameter):
15
15
  def parameter_type(self) -> ParameterType:
16
16
  return "RESERVED"
17
17
 
18
- def is_required(self):
18
+ @property
19
+ def is_required(self) -> bool:
19
20
  return False
20
21
 
21
- def is_optional(self):
22
+ @property
23
+ def is_settable(self) -> bool:
22
24
  return False
23
25
 
24
26
  @property
@@ -13,11 +13,13 @@ class SystemParameter(ParameterWithDOP):
13
13
  def parameter_type(self) -> ParameterType:
14
14
  return "SYSTEM"
15
15
 
16
- def is_required(self):
16
+ @property
17
+ def is_required(self) -> bool:
17
18
  raise NotImplementedError("SystemParameter.is_required is not implemented yet.")
18
19
 
19
- def is_optional(self):
20
- raise NotImplementedError("SystemParameter.is_optional is not implemented yet.")
20
+ @property
21
+ def is_settable(self) -> bool:
22
+ raise NotImplementedError("SystemParameter.is_settable is not implemented yet.")
21
23
 
22
24
  def get_coded_value(self):
23
25
  raise NotImplementedError("Encoding a SystemParameter is not implemented yet.")
@@ -14,11 +14,13 @@ class TableEntryParameter(Parameter):
14
14
  def parameter_type(self) -> ParameterType:
15
15
  return "TABLE-ENTRY"
16
16
 
17
- def is_required(self):
17
+ @property
18
+ def is_required(self) -> bool:
18
19
  raise NotImplementedError("TableKeyParameter.is_required is not implemented yet.")
19
20
 
20
- def is_optional(self):
21
- raise NotImplementedError("TableKeyParameter.is_optional is not implemented yet.")
21
+ @property
22
+ def is_settable(self) -> bool:
23
+ raise NotImplementedError("TableKeyParameter.is_settable is not implemented yet.")
22
24
 
23
25
  def get_coded_value(self):
24
26
  raise NotImplementedError("Encoding a TableKeyParameter is not implemented yet.")
@@ -84,11 +84,15 @@ class TableKeyParameter(Parameter):
84
84
  def table_row(self) -> Optional["TableRow"]:
85
85
  return self._table_row
86
86
 
87
- def is_required(self):
88
- return self._table_row is None
87
+ @property
88
+ def is_required(self) -> bool:
89
+ # TABLE-KEY parameters can be implicitly determined from the
90
+ # corresponding TABLE-STRUCT
91
+ return False
89
92
 
90
- def is_optional(self):
91
- return not self.is_required()
93
+ @property
94
+ def is_settable(self) -> bool:
95
+ return True
92
96
 
93
97
  def get_coded_value(self, physical_value=None) -> Any:
94
98
  key_dop = self.table.key_dop
@@ -50,11 +50,13 @@ class TableStructParameter(Parameter):
50
50
  def table_key(self) -> TableKeyParameter:
51
51
  return self._table_key
52
52
 
53
+ @property
53
54
  def is_required(self):
54
55
  return True
55
56
 
56
- def is_optional(self):
57
- return False
57
+ @property
58
+ def is_settable(self):
59
+ return True
58
60
 
59
61
  def get_coded_value(self, physical_value=None):
60
62
  raise EncodeError("TableStructParameters cannot be converted to "
@@ -47,11 +47,13 @@ class ValueParameter(ParameterWithDOP):
47
47
  def physical_default_value(self) -> Optional[AtomicOdxType]:
48
48
  return self._physical_default_value
49
49
 
50
+ @property
50
51
  def is_required(self) -> bool:
51
- return self.physical_default_value is None
52
+ return self._physical_default_value is None
52
53
 
53
- def is_optional(self) -> bool:
54
- return not self.is_required()
54
+ @property
55
+ def is_settable(self) -> bool:
56
+ return True
55
57
 
56
58
  def get_coded_value(self, physical_value: Optional[AtomicOdxType] = None):
57
59
  if physical_value is not None:
@@ -0,0 +1,74 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass
3
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
4
+ from xml.etree import ElementTree
5
+
6
+ from .dataobjectproperty import DataObjectProperty
7
+ from .decodestate import DecodeState
8
+ from .encodestate import EncodeState
9
+ from .exceptions import odxrequire
10
+ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
11
+
12
+ if TYPE_CHECKING:
13
+ from .diaglayer import DiagLayer
14
+
15
+
16
+ @dataclass
17
+ class PositionedDataObjectProperty:
18
+ """
19
+ This class represents a wrapper for DataObjectProperty that adds position information
20
+ used by Switch Key in the Multiplexer.
21
+ used by Number Of Items in the DynamicLengthField.
22
+ """
23
+
24
+ byte_position: int
25
+ bit_position: Optional[int]
26
+ dop_ref: OdxLinkRef
27
+
28
+ def __post_init__(self):
29
+ self._dop: DataObjectProperty = None # type: ignore
30
+
31
+ @staticmethod
32
+ def from_et(et_element: ElementTree.Element,
33
+ doc_frags: List[OdxDocFragment]) -> "PositionedDataObjectProperty":
34
+ byte_position = int(odxrequire(et_element.findtext("BYTE-POSITION", "0")))
35
+ bit_position_str = et_element.findtext("BIT-POSITION")
36
+ bit_position = int(bit_position_str) if bit_position_str is not None else None
37
+ dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DATA-OBJECT-PROP-REF"), doc_frags))
38
+
39
+ return PositionedDataObjectProperty(
40
+ byte_position=byte_position,
41
+ bit_position=bit_position,
42
+ dop_ref=dop_ref,
43
+ )
44
+
45
+ @property
46
+ def dop(self) -> DataObjectProperty:
47
+ return self._dop
48
+
49
+ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
50
+ return {}
51
+
52
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
53
+ self._dop = odxrequire(odxlinks.resolve(self.dop_ref, DataObjectProperty))
54
+
55
+ def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
56
+ pass
57
+
58
+ def convert_physical_to_bytes(self, physical_value, encode_state: EncodeState) -> bytes:
59
+
60
+ bit_position = self.bit_position if self.bit_position is not None else 0
61
+ dop_bytes = self.dop.convert_physical_to_bytes(physical_value, encode_state, bit_position)
62
+
63
+ return b'\0' * self.byte_position + dop_bytes
64
+
65
+ def convert_bytes_to_physical(self, decode_state: DecodeState) -> Tuple[Any, int]:
66
+
67
+ byte_code = decode_state.coded_message[decode_state.next_byte_position:]
68
+ state = DecodeState(
69
+ coded_message=byte_code[self.byte_position:],
70
+ parameter_values=dict(),
71
+ next_byte_position=0,
72
+ )
73
+ bit_position_int = (self.bit_position if self.bit_position is not None else 0)
74
+ return self.dop.convert_bytes_to_physical(state, bit_position=bit_position_int)
odxtools/progcode.py CHANGED
@@ -1,10 +1,9 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from enum import Enum
4
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast
3
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional
5
4
  from xml.etree import ElementTree
6
5
 
7
- from .exceptions import odxraise, odxrequire
6
+ from .exceptions import odxrequire
8
7
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
9
8
 
10
9
  if TYPE_CHECKING:
odxtools/tablerow.py CHANGED
@@ -3,11 +3,10 @@ from dataclasses import dataclass
3
3
  from typing import TYPE_CHECKING, Any, Dict, List, Optional
4
4
  from xml.etree import ElementTree
5
5
 
6
- from odxtools.element import IdentifiableElement
7
-
8
6
  from .basicstructure import BasicStructure
9
7
  from .createsdgs import create_sdgs_from_et
10
8
  from .dataobjectproperty import DataObjectProperty
9
+ from .element import IdentifiableElement
11
10
  from .exceptions import odxassert, odxrequire
12
11
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
13
12
  from .odxtypes import AtomicOdxType
@@ -3,17 +3,11 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
  -#}
5
5
 
6
+ {%- import('macros/printElementID.xml.jinja2') as peid %}
7
+
6
8
  {%- macro printAdditionalAudience(audience) -%}
7
9
  <ADDITIONAL-AUDIENCE ID="{{audience.odx_id.local_id}}">
8
- <SHORT-NAME>{{audience.short_name}}</SHORT-NAME>
9
- {%- if audience.long_name %}
10
- <LONG-NAME>{{audience.long_name}}</LONG-NAME>
11
- {%- endif %}
12
- {%- if audience.description is string and audience.description.strip() %}
13
- <DESC>
14
- {{audience.description}}
15
- </DESC>
16
- {%- endif %}
10
+ {{ peid.printElementID(audience)|indent(1) }}
17
11
  </ADDITIONAL-AUDIENCE>
18
12
  {%- endmacro -%}
19
13
 
@@ -3,19 +3,12 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
  -#}
5
5
 
6
+ {%- import('macros/printElementID.xml.jinja2') as peid %}
6
7
  {%- import('macros/printSpecialData.xml.jinja2') as psd %}
7
8
 
8
9
  {%- macro printCompanyData(company_data) -%}
9
10
  <COMPANY-DATA ID="{{company_data.odx_id.local_id}}">
10
- <SHORT-NAME>{{company_data.short_name|e}}</SHORT-NAME>
11
- {%- if company_data.long_name is not none %}
12
- <LONG-NAME>{{company_data.long_name|e}}</LONG-NAME>
13
- {%- endif %}
14
- {%- if company_data.description is not none %}
15
- <DESC>
16
- {{company_data.description}}
17
- </DESC>
18
- {%- endif %}
11
+ {{ peid.printElementID(company_data)|indent(1) }}
19
12
  {%- if company_data.roles is not none %}
20
13
  <ROLES>
21
14
  {%- for role in company_data.roles %}
@@ -27,15 +20,7 @@
27
20
  <TEAM-MEMBERS>
28
21
  {%- for team_member in company_data.team_members %}
29
22
  <TEAM-MEMBER ID="{{team_member.odx_id.local_id}}">
30
- <SHORT-NAME>{{team_member.short_name|e}}</SHORT-NAME>
31
- {%- if company_data.long_name is not none %}
32
- <LONG-NAME>{{team_member.long_name|e}}</LONG-NAME>
33
- {%- endif %}
34
- {%- if company_data.description is not none %}
35
- <DESC>
36
- {{team_member.description}}
37
- </DESC>
38
- {%- endif %}
23
+ {{ peid.printElementID(team_member)|indent(3) }}
39
24
  {%- if team_member.roles is not none %}
40
25
  <ROLES>
41
26
  {%- for role in team_member.roles %}
@@ -75,15 +60,7 @@
75
60
  <RELATED-DOC>
76
61
  {%- if rd.xdoc is not none %}
77
62
  <XDOC>
78
- <SHORT-NAME>{{rd.xdoc.short_name|e}}</SHORT-NAME>
79
- {%- if rd.xdoc.long_name is not none %}
80
- <LONG-NAME>{{rd.xdoc.long_name|e}}</LONG-NAME>
81
- {%- endif %}
82
- {%- if rd.xdoc.description is not none %}
83
- <DESC>
84
- {{rd.xdoc.description}}
85
- </DESC>
86
- {%- endif %}
63
+ {{ peid.printElementID(rd.xdoc)|indent(5) }}
87
64
  {%- if rd.xdoc.number is not none %}
88
65
  <NUMBER>{{rd.xdoc.number|e}}</NUMBER>
89
66
  {%- endif %}
@@ -3,6 +3,8 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
  -#}
5
5
 
6
+ {%- import('macros/printElementID.xml.jinja2') as peid %}
7
+
6
8
  {%- macro printComplexValue(cv) %}
7
9
  <COMPLEX-VALUE>
8
10
  {%- for val in cv %}
@@ -41,15 +43,7 @@
41
43
  CPTYPE="{{cp.cptype.value}}"
42
44
  {{make_xml_attrib("DISPLAY-LEVEL", cp.display_level)}}
43
45
  CPUSAGE="{{cp.cpusage.value}}">
44
- <SHORT-NAME>{{cp.short_name}}</SHORT-NAME>
45
- {%- if cp.long_name and cp.long_name.strip() %}
46
- <LONG-NAME>{{cp.long_name|e}}</LONG-NAME>
47
- {%- endif %}
48
- {%- if cp.description and cp.description.strip() %}
49
- <DESC>
50
- {{cp.description}}
51
- </DESC>
52
- {%- endif %}
46
+ {{ peid.printElementID(cp)|indent(1) }}
53
47
  <PHYSICAL-DEFAULT-VALUE>{{cp.physical_default_value}}</PHYSICAL-DEFAULT-VALUE>
54
48
  <DATA-OBJECT-PROP-REF ID-REF="{{cp.dop_ref.ref_id}}" />
55
49
  </COMPARAM>
@@ -63,15 +57,7 @@
63
57
  CPUSAGE="{{cp.cpusage.value}}"
64
58
  {{make_bool_xml_attrib("ALLOW-MULTIPLE-VALUES", cp.allow_multiple_values_raw)}}
65
59
  {#- #}>
66
- <SHORT-NAME>{{cp.short_name}}</SHORT-NAME>
67
- {%- if cp.long_name and cp.long_name.strip() %}
68
- <LONG-NAME>{{cp.long_name|e}}</LONG-NAME>
69
- {%- endif %}
70
- {%- if cp.description and cp.description.strip() %}
71
- <DESC>
72
- {{cp.description}}
73
- </DESC>
74
- {%- endif %}
60
+ {{ peid.printElementID(cp)|indent(1) }}
75
61
  {%- for sub_cp in cp.comparams %}
76
62
  {{- printGenericComparam(sub_cp) | indent(1, first=True) }}
77
63
  {%- endfor %}
@@ -3,6 +3,7 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
  -#}
5
5
 
6
+ {%- import('macros/printElementID.xml.jinja2') as peid %}
6
7
  {%- import('macros/printAdminData.xml.jinja2') as pad %}
7
8
  {%- import('macros/printSpecialData.xml.jinja2') as psd %}
8
9
 
@@ -164,13 +165,7 @@
164
165
 
165
166
  {%- macro printDOP(dop, tag_name) %}
166
167
  <{{tag_name}} ID="{{dop.odx_id.local_id}}">
167
- <SHORT-NAME>{{dop.short_name}}</SHORT-NAME>
168
- {%- if dop.long_name %}
169
- <LONG-NAME>{{dop.long_name|e}}</LONG-NAME>
170
- {%- endif %}
171
- {%- if dop.description %}
172
- <DESC>{{dop.description}}</DESC>
173
- {%- endif %}
168
+ {{ peid.printElementID(dop)|indent(1) }}
174
169
  {%- if dop.admin_data %}
175
170
  {{- pad.printAdminData(dop.admin_data)|indent(2, first=True) }}
176
171
  {%- endif %}
@@ -192,8 +187,7 @@
192
187
 
193
188
  {%- macro printDTCDOP(dop) %}
194
189
  <DTC-DOP ID="{{dop.odx_id.local_id}}">
195
- <SHORT-NAME>{{dop.short_name}}</SHORT-NAME>
196
- <LONG-NAME>{{dop.long_name|e}}</LONG-NAME>
190
+ {{ peid.printElementID(dop)|indent(1) }}
197
191
  {{- psd.printSpecialDataGroups(dop.sdgs)|indent(1, first=True) }}
198
192
  {{- printDiagCodedType(dop.diag_coded_type)|indent(1, first=True) }}
199
193
  {{- printPhysicalType(dop.physical_type)|indent(1, first=True) }}
@@ -0,0 +1,22 @@
1
+ {#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ -#}
5
+
6
+ {%- import('macros/printElementID.xml.jinja2') as peid %}
7
+
8
+ {%- macro printDynamicLengthField(dlf) -%}
9
+ <DYNAMIC-LENGTH-FIELD ID="{{dlf.odx_id.local_id}}">
10
+ {{ peid.printElementID(dlf)|indent(1) }}
11
+ <BASIC-STRUCTURE-REF ID-REF="{{dlf.structure_ref.ref_id}}" />
12
+ <OFFSET>{{dlf.offset}}</OFFSET>
13
+ <DETERMINE-NUMBER-OF-ITEMS>
14
+ {%- set dni = dlf.determine_number_of_items %}
15
+ <BYTE-POSITION>{{dni.byte_position}}</BYTE-POSITION>
16
+ {%- if dni.bit_position is not none %}
17
+ <BIT-POSITION>{{dni.bit_position}}</BIT-POSITION>
18
+ {%- endif %}
19
+ <DATA-OBJECT-PROP-REF ID-REF="{{dni.dop_ref.ref_id}}" />
20
+ </DETERMINE-NUMBER-OF-ITEMS>
21
+ </DYNAMIC-LENGTH-FIELD>
22
+ {%- endmacro -%}
@@ -3,12 +3,12 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
  -#}
5
5
 
6
- {%- macro printElementID(element) -%}
7
- <SHORT-NAME>{{ element.short_name }}</SHORT-NAME>
8
- {%- if element.long_name is string and element.long_name.strip() %}
9
- <LONG-NAME>{{ element.long_name|e }}</LONG-NAME>
6
+ {%- macro printElementID(obj) -%}
7
+ <SHORT-NAME>{{ obj.short_name }}</SHORT-NAME>
8
+ {%- if obj.long_name %}
9
+ <LONG-NAME>{{ obj.long_name|e }}</LONG-NAME>
10
10
  {%- endif %}
11
- {%- if element.description is string and element.description.strip() %}
12
- <DESC>{{ element.description }}</DESC>
11
+ {%- if obj.description %}
12
+ <DESC>{{ obj.description }}</DESC>
13
13
  {%- endif %}
14
14
  {%- endmacro -%}
@@ -3,10 +3,11 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
  -#}
5
5
 
6
+ {%- import('macros/printElementID.xml.jinja2') as peid %}
7
+
6
8
  {%- macro printEndOfPdu(eopdu) -%}
7
9
  <END-OF-PDU-FIELD ID="{{eopdu.odx_id.local_id}}">
8
- <SHORT-NAME>{{eopdu.short_name}}</SHORT-NAME>
9
- <LONG-NAME>{{eopdu.long_name|e}}</LONG-NAME>
10
+ {{ peid.printElementID(eopdu)|indent(1) }}
10
11
  <BASIC-STRUCTURE-REF ID-REF="{{eopdu.structure_ref.ref_id}}" />
11
12
  </END-OF-PDU-FIELD>
12
13
  {%- endmacro -%}
@@ -3,12 +3,12 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
  -#}
5
5
 
6
+ {%- import('macros/printElementID.xml.jinja2') as peid %}
6
7
  {%- import('macros/printParam.xml.jinja2') as pparam %}
7
8
 
8
9
  {%- macro printEnvData(env_data) %}
9
10
  <ENV-DATA ID="{{env_data.odx_id.local_id}}">
10
- <SHORT-NAME>{{env_data.short_name}}</SHORT-NAME>
11
- <LONG-NAME>{{env_data.long_name}}</LONG-NAME>
11
+ {{ peid.printElementID(env_data)|indent(1) }}
12
12
  <PARAMS>
13
13
  {%- for param in env_data.parameters %}
14
14
  {{pparam.printParam(param) | indent(6, first=True) }}
@@ -3,10 +3,11 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
  -#}
5
5
 
6
+ {%- import('macros/printElementID.xml.jinja2') as peid %}
7
+
6
8
  {%- macro printEnvDataDesc(env_data_desc) %}
7
9
  <ENV-DATA-DESC ID="{{env_data_desc.odx_id.local_id}}">
8
- <SHORT-NAME>{{env_data_desc.short_name}}</SHORT-NAME>
9
- <LONG-NAME>{{env_data_desc.long_name}}</LONG-NAME>
10
+ {{ peid.printElementID(env_data_desc)|indent(1) }}
10
11
  <PARAM-SNREF SHORT-NAME="{{env_data_desc.param_snref}}"/>
11
12
  <ENV-DATA-REFS>
12
13
  {%- for env_data_ref in env_data_desc.env_data_refs %}
@@ -4,16 +4,10 @@
4
4
  # SPDX-License-Identifier: MIT
5
5
  -#}
6
6
 
7
+ {%- import('macros/printElementID.xml.jinja2') as peid %}
8
+
7
9
  {%- macro printFunctionalClass(fc) -%}
8
10
  <FUNCT-CLASS ID="{{fc.odx_id.local_id}}">
9
- <SHORT-NAME>{{fc.short_name}}</SHORT-NAME>
10
- {%- if fc.long_name is string and fc.long_name.strip() %}
11
- <LONG-NAME>{{fc.long_name}}</LONG-NAME>
12
- {%- endif %}
13
- {%- if fc.description is string and fc.description.strip() %}
14
- <DESC>
15
- {{fc.description}}
16
- </DESC>
17
- {%- endif %}
11
+ {{ peid.printElementID(fc)|indent(1) }}
18
12
  </FUNCT-CLASS>
19
13
  {%- endmacro -%}
@@ -3,10 +3,11 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
  -#}
5
5
 
6
+ {%- import('macros/printElementID.xml.jinja2') as peid %}
7
+
6
8
  {%- macro printMux(mux) %}
7
9
  <MUX ID="{{mux.odx_id.local_id}}">
8
- <SHORT-NAME>{{mux.short_name}}</SHORT-NAME>
9
- <LONG-NAME>{{mux.long_name|e}}</LONG-NAME>
10
+ {{ peid.printElementID(mux)|indent(1) }}
10
11
  <BYTE-POSITION>{{mux.byte_position}}</BYTE-POSITION>
11
12
  <SWITCH-KEY>
12
13
  <BYTE-POSITION>{{mux.switch_key.byte_position}}</BYTE-POSITION>
@@ -17,20 +18,26 @@
17
18
  </SWITCH-KEY>
18
19
  {%- if mux.default_case is not none %}
19
20
  <DEFAULT-CASE>
20
- <SHORT-NAME>{{mux.default_case.short_name}}</SHORT-NAME>
21
- <LONG-NAME>{{mux.default_case.long_name}}</LONG-NAME>
21
+ {{ peid.printElementID(mux.default_case)|indent(4) }}
22
22
  {%- if mux.default_case.structure_ref is not none %}
23
23
  <STRUCTURE-REF ID-REF="{{mux.default_case.structure_ref.ref_id}}"/>
24
24
  {%- endif %}
25
+ {%- if mux.default_case.structure_snref is not none %}
26
+ <STRUCTURE-SNREF SHORT_NAME="{{mux.default_case.structure_snref}}"/>
27
+ {%- endif %}
25
28
  </DEFAULT-CASE>
26
29
  {%- endif %}
27
30
  {%- if mux.cases %}
28
31
  <CASES>
29
32
  {%- for case in mux.cases %}
30
33
  <CASE>
31
- <SHORT-NAME>{{case.short_name}}</SHORT-NAME>
32
- <LONG-NAME>{{case.long_name}}</LONG-NAME>
34
+ {{ peid.printElementID(case)|indent(6) }}
35
+ {%- if case.structure_ref is not none %}
33
36
  <STRUCTURE-REF ID-REF="{{case.structure_ref.ref_id}}"/>
37
+ {%- endif %}
38
+ {%- if case.structure_snref is not none %}
39
+ <STRUCTURE-SNREF SHORT_NAME="{{case.structure_snref}}"/>
40
+ {%- endif %}
34
41
  <LOWER-LIMIT>{{case.lower_limit}}</LOWER-LIMIT>
35
42
  <UPPER-LIMIT>{{case.upper_limit}}</UPPER-LIMIT>
36
43
  </CASE>