odxtools 10.1.0__py3-none-any.whl → 10.2.0__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 (107) hide show
  1. odxtools/addrdeffilter.py +33 -0
  2. odxtools/addrdefphyssegment.py +33 -0
  3. odxtools/checksum.py +67 -0
  4. odxtools/checksumresult.py +7 -0
  5. odxtools/cli/compare.py +143 -170
  6. odxtools/database.py +24 -4
  7. odxtools/datablock.py +153 -0
  8. odxtools/datafile.py +23 -0
  9. odxtools/dataformat.py +39 -0
  10. odxtools/dataformatselection.py +9 -0
  11. odxtools/description.py +2 -5
  12. odxtools/diagdatadictionaryspec.py +1 -3
  13. odxtools/direction.py +7 -0
  14. odxtools/ecumem.py +71 -0
  15. odxtools/ecumemconnector.py +136 -0
  16. odxtools/encryptcompressmethod.py +39 -0
  17. odxtools/encryptcompressmethodtype.py +13 -0
  18. odxtools/expectedident.py +40 -0
  19. odxtools/externflashdata.py +34 -0
  20. odxtools/filter.py +32 -0
  21. odxtools/flash.py +88 -0
  22. odxtools/flashclass.py +32 -0
  23. odxtools/flashdata.py +70 -0
  24. odxtools/fwchecksum.py +7 -0
  25. odxtools/fwsignature.py +7 -0
  26. odxtools/identdesc.py +54 -0
  27. odxtools/identvalue.py +32 -0
  28. odxtools/identvaluetype.py +14 -0
  29. odxtools/internflashdata.py +33 -0
  30. odxtools/loadfile.py +1 -1
  31. odxtools/mem.py +80 -0
  32. odxtools/modification.py +3 -2
  33. odxtools/negoffset.py +21 -0
  34. odxtools/ownident.py +38 -0
  35. odxtools/physicaltype.py +12 -10
  36. odxtools/physmem.py +52 -0
  37. odxtools/physsegment.py +42 -0
  38. odxtools/posoffset.py +21 -0
  39. odxtools/security.py +42 -0
  40. odxtools/securitymethod.py +7 -0
  41. odxtools/segment.py +63 -0
  42. odxtools/session.py +88 -0
  43. odxtools/sessiondesc.py +101 -0
  44. odxtools/sessionsubelemtype.py +14 -0
  45. odxtools/sizedeffilter.py +33 -0
  46. odxtools/sizedefphyssegment.py +33 -0
  47. odxtools/specialdata.py +2 -1
  48. odxtools/targetaddroffset.py +13 -0
  49. odxtools/templates/comparam-spec.odx-c.xml.jinja2 +1 -0
  50. odxtools/templates/comparam-subset.odx-cs.xml.jinja2 +1 -0
  51. odxtools/templates/diag_layer_container.odx-d.xml.jinja2 +2 -1
  52. odxtools/templates/flash.odx-f.xml.jinja2 +42 -0
  53. odxtools/templates/macros/printAdminData.xml.jinja2 +4 -4
  54. odxtools/templates/macros/printAudience.xml.jinja2 +3 -3
  55. odxtools/templates/macros/printChecksum.xml.jinja2 +36 -0
  56. odxtools/templates/macros/printComparam.xml.jinja2 +1 -1
  57. odxtools/templates/macros/printComparamRef.xml.jinja2 +1 -3
  58. odxtools/templates/macros/printCompuMethod.xml.jinja2 +1 -1
  59. odxtools/templates/macros/printDOP.xml.jinja2 +3 -3
  60. odxtools/templates/macros/printDatablock.xml.jinja2 +78 -0
  61. odxtools/templates/macros/printDiagComm.xml.jinja2 +2 -2
  62. odxtools/templates/macros/printDiagLayer.xml.jinja2 +2 -1
  63. odxtools/templates/macros/printDiagVariable.xml.jinja2 +4 -4
  64. odxtools/templates/macros/printDynDefinedSpec.xml.jinja2 +3 -3
  65. odxtools/templates/macros/printDynamicEndmarkerField.xml.jinja2 +2 -2
  66. odxtools/templates/macros/printDynamicLengthField.xml.jinja2 +2 -2
  67. odxtools/templates/macros/printEcuMem.xml.jinja2 +24 -0
  68. odxtools/templates/macros/printEcuMemConnector.xml.jinja2 +58 -0
  69. odxtools/templates/macros/printEndOfPdu.xml.jinja2 +1 -1
  70. odxtools/templates/macros/printEnvDataDesc.xml.jinja2 +1 -1
  71. odxtools/templates/macros/printExpectedIdent.xml.jinja2 +21 -0
  72. odxtools/templates/macros/printFlashdata.xml.jinja2 +43 -0
  73. odxtools/templates/macros/printIdentDesc.xml.jinja2 +17 -0
  74. odxtools/templates/macros/printMem.xml.jinja2 +35 -0
  75. odxtools/templates/macros/printMux.xml.jinja2 +3 -3
  76. odxtools/templates/macros/printOdxCategory.xml.jinja2 +4 -4
  77. odxtools/templates/macros/printOwnIdent.xml.jinja2 +17 -0
  78. odxtools/templates/macros/printParam.xml.jinja2 +4 -4
  79. odxtools/templates/macros/printParentRef.xml.jinja2 +1 -5
  80. odxtools/templates/macros/printPhysMem.xml.jinja2 +20 -0
  81. odxtools/templates/macros/printPhysSegment.xml.jinja2 +33 -0
  82. odxtools/templates/macros/printPreConditionStateRef.xml.jinja2 +1 -1
  83. odxtools/templates/macros/printProtStack.xml.jinja2 +1 -1
  84. odxtools/templates/macros/printProtocol.xml.jinja2 +1 -1
  85. odxtools/templates/macros/printSecurity.xml.jinja2 +37 -0
  86. odxtools/templates/macros/printSegment.xml.jinja2 +31 -0
  87. odxtools/templates/macros/printService.xml.jinja2 +3 -3
  88. odxtools/templates/macros/printSession.xml.jinja2 +45 -0
  89. odxtools/templates/macros/printSessionDesc.xml.jinja2 +40 -0
  90. odxtools/templates/macros/printSingleEcuJob.xml.jinja2 +3 -3
  91. odxtools/templates/macros/printSpecialData.xml.jinja2 +2 -2
  92. odxtools/templates/macros/printStateTransitionRef.xml.jinja2 +1 -1
  93. odxtools/templates/macros/printStaticField.xml.jinja2 +1 -1
  94. odxtools/templates/macros/printSubComponent.xml.jinja2 +3 -3
  95. odxtools/templates/macros/printTable.xml.jinja2 +6 -6
  96. odxtools/templates/macros/printUnitSpec.xml.jinja2 +2 -2
  97. odxtools/text.py +2 -6
  98. odxtools/utils.py +22 -1
  99. odxtools/validityfor.py +30 -0
  100. odxtools/version.py +2 -2
  101. odxtools/writepdxfile.py +70 -21
  102. {odxtools-10.1.0.dist-info → odxtools-10.2.0.dist-info}/METADATA +1 -1
  103. {odxtools-10.1.0.dist-info → odxtools-10.2.0.dist-info}/RECORD +107 -50
  104. {odxtools-10.1.0.dist-info → odxtools-10.2.0.dist-info}/WHEEL +1 -1
  105. {odxtools-10.1.0.dist-info → odxtools-10.2.0.dist-info}/entry_points.txt +0 -0
  106. {odxtools-10.1.0.dist-info → odxtools-10.2.0.dist-info}/licenses/LICENSE +0 -0
  107. {odxtools-10.1.0.dist-info → odxtools-10.2.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,20 @@
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
+ {%- import('macros/printPhysSegment.xml.jinja2') as ppseg %}
8
+
9
+ {%- macro printPhysMem(phys_mem) -%}
10
+ <PHYS-MEM {{peid.printElementIdAttribs(phys_mem)}}>
11
+ {{ peid.printElementIdSubtags(phys_mem)|indent(1) }}
12
+ {%- if phys_mem.phys_segments %}
13
+ <PHYS-SEGMENTS>
14
+ {%- for phys_segment in phys_mem.phys_segments %}
15
+ {{ ppseg.printPhysSegment(phys_segment)|indent(4) }}
16
+ {%- endfor %}
17
+ </PHYS-SEGMENTS>
18
+ {%- endif %}
19
+ </PHYS-MEM>
20
+ {%- endmacro -%}
@@ -0,0 +1,33 @@
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 printPhysSegment(phys_segment) -%}
9
+ <PHYS-SEGMENT {{-peid.printElementIdAttribs(phys_segment)}}
10
+ {%- if phys_segment.size is defined %}
11
+ {#- #}xsi:type="SIZEDEF-PHYS-SEGMENT"
12
+ {%- elif phys_segment.end_address is defined %}
13
+ {#- #}xsi:type="ADDRDEF-PHYS-SEGMENT"
14
+ {%- endif %}
15
+ {#- #}>
16
+ {{ peid.printElementIdSubtags(phys_segment)|indent(2) }}
17
+ {%- if phys_segment.fillbyte is not none %}
18
+ {%- set num_nibbles = (phys_segment.fillbyte.bit_length() + 7) // 8 * 2 %}
19
+ <FILLBYTE>{{ ("%%0%dX" | format(num_nibbles | int)) | format(phys_segment.fillbyte | int) }}</FILLBYTE>
20
+ {%- endif %}
21
+ {%- if phys_segment.block_size is not none %}
22
+ <BLOCK-SIZE>{{ phys_segment.block_size }}</BLOCK-SIZE>
23
+ {%- endif %}
24
+ {%- set num_nibbles = (phys_segment.start_address.bit_length() + 7) // 8 * 2 %}
25
+ <START-ADDRESS>{{ ("%%0%dX" | format(num_nibbles | int)) | format(phys_segment.start_address | int) }}</START-ADDRESS>
26
+ {%- if phys_segment.size is defined %}
27
+ <SIZE>{{phys_segment.size}}</SIZE>
28
+ {%- elif phys_segment.end_address is defined %}
29
+ {%- set num_nibbles = (phys_segment.end_address.bit_length() + 7) // 8 * 2 %}
30
+ <END-ADDRESS>{{ ("%%0%dX" | format(num_nibbles | int)) | format(phys_segment.end_address | int) }}</END-ADDRESS>
31
+ {%- endif %}
32
+ </PHYS-SEGMENT>
33
+ {%- endmacro -%}
@@ -4,7 +4,7 @@
4
4
  -#}
5
5
 
6
6
  {%- macro printPreConditionStateRef(ps_ref) -%}
7
- <PRE-CONDITION-STATE-REF ID-REF="{{ps_ref.ref_id}}">
7
+ <PRE-CONDITION-STATE-REF {{make_ref_attribs(ps_ref)}}>
8
8
  {%- if ps_ref.value is not none %}
9
9
  <VALUE>{{ ps_ref.value }}</VALUE>
10
10
  {%- endif %}
@@ -14,7 +14,7 @@
14
14
  {%- if ps.comparam_subset_refs %}
15
15
  <COMPARAM-SUBSET-REFS>
16
16
  {%- for csr in ps.comparam_subset_refs %}
17
- <COMPARAM-SUBSET-REF ID-REF="{{csr.ref_id}}" DOCREF="{{csr.ref_id}}" DOCTYPE="COMPARAM-SUBSET"/>
17
+ <COMPARAM-SUBSET-REF {{make_ref_attribs(csr)}}/>
18
18
  {%- endfor %}
19
19
  </COMPARAM-SUBSET-REFS>
20
20
  {%- endif %}
@@ -13,7 +13,7 @@
13
13
  {%- set dlr = protocol.protocol_raw %}
14
14
 
15
15
  {%- set cps_docfrag = dlr.comparam_spec_ref.ref_docs[-1] %}
16
- <COMPARAM-SPEC-REF ID-REF="{{dlr.comparam_spec_ref.ref_id}}" DOCREF="{{cps_docfrag.doc_name}}" DOCTYPE="{{cps_docfrag.doc_type.value}}" />
16
+ <COMPARAM-SPEC-REF {{make_ref_attribs(dlr.comparam_spec_ref)}} />
17
17
 
18
18
  {%- if dlr.prot_stack_snref is not none %}
19
19
  <PROT-STACK-SNREF SHORT-NAME="{{ dlr.prot_stack_snref }}" />
@@ -0,0 +1,37 @@
1
+ {#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ -#}
5
+
6
+ {%- macro printSecurity(security) -%}
7
+ <SECURITY>
8
+ {%- if security.security_method is not none %}
9
+ <SECURITY-METHOD
10
+ {%- if security.security_method.value_type is not none %}
11
+ {#- #} TYPE="{{ security.security_method.value_type.value }}"
12
+ {%- endif %}
13
+ {#- #}>{{security.security_method.value}}</SECURITY-METHOD>
14
+ {%- endif %}
15
+ {%- if security.fw_signature is not none %}
16
+ <FW-SIGNATURE
17
+ {%- if security.fw_signature.value_type is not none %}
18
+ {#- #} TYPE="{{ security.fw_signature.value_type.value }}"
19
+ {%- endif %}
20
+ {#- #}>{{security.fw_signature.value}}</FW-SIGNATURE>
21
+ {%- endif %}
22
+ {%- if security.fw_checksum is not none %}
23
+ <FW-CHECKSUM
24
+ {%- if security.fw_checksum.value_type is not none %}
25
+ {#- #} TYPE="{{ security.fw_checksum.value_type.value }}"
26
+ {%- endif %}
27
+ {#- #}>{{security.fw_checksum.value}}</FW-CHECKSUM>
28
+ {%- endif %}
29
+ {%- if security.validity_for is not none %}
30
+ <VALIDITY-FOR
31
+ {%- if security.validity_for.value_type is not none %}
32
+ {#- #} TYPE="{{ security.validity_for.value_type.value }}"
33
+ {%- endif %}
34
+ {#- #}>{{security.validity_for.value}}</VALIDITY-FOR>
35
+ {%- endif %}
36
+ </SECURITY>
37
+ {%- endmacro -%}
@@ -0,0 +1,31 @@
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 printSegment(segment) -%}
9
+ <SEGMENT {{peid.printElementIdAttribs(segment)}}>
10
+ {{ peid.printElementIdSubtags(segment)|indent(1) }}
11
+ {%- set num_nibbles = (segment.source_start_address.bit_length() + 7) // 8 * 2 %}
12
+ <SOURCE-START-ADDRESS>{{("%%0%dX" | format(num_nibbles | int)) | format(segment.source_start_address | int)}}</SOURCE-START-ADDRESS>
13
+ {%- if segment.compressed_size is not none %}
14
+ <COMPRESSED-SIZE>{{segment.compressed_size}}</COMPRESSED-SIZE>
15
+ {%- endif %}
16
+ {%- if segment.uncompressed_size is not none %}
17
+ <UNCOMPRESSED-SIZE>{{segment.uncompressed_size}}</UNCOMPRESSED-SIZE>
18
+ {%- endif %}
19
+ {%- if segment.source_end_address is not none %}
20
+ {%- set num_nibbles = (segment.source_end_address.bit_length() + 7) // 8 * 2 %}
21
+ <SOURCE-END-ADDRESS>{{("%%0%dX" | format(num_nibbles | int)) | format(segment.source_end_address | int)}}</SOURCE-END-ADDRESS>
22
+ {%- endif %}
23
+ {%- if segment.encrypt_compress_method is not none %}
24
+ <ENCRYPT-COMPRESS-METHOD
25
+ {%- if segment.encrypt_compress_method.value_type is not none %}
26
+ {#- #} TYPE="{{ segment.encrypt_compress_method.value_type.value }}"
27
+ {%- endif %}
28
+ {#- #}>{{segment.encrypt_compress_method.value}}</ENCRYPT-COMPRESS-METHOD>
29
+ {%- endif %}
30
+ </SEGMENT>
31
+ {%- endmacro -%}
@@ -56,19 +56,19 @@
56
56
  </COMPARAM-REFS>
57
57
  {%- endif%}
58
58
  {%- if service.request_ref %}
59
- <REQUEST-REF ID-REF="{{service.request_ref.ref_id}}"/>
59
+ <REQUEST-REF {{make_ref_attribs(service.request_ref)}}/>
60
60
  {%- endif %}
61
61
  {%- if service.pos_response_refs %}
62
62
  <POS-RESPONSE-REFS>
63
63
  {%- for ref in service.pos_response_refs %}
64
- <POS-RESPONSE-REF ID-REF="{{ref.ref_id}}" />
64
+ <POS-RESPONSE-REF {{make_ref_attribs(ref)}} />
65
65
  {%- endfor %}
66
66
  </POS-RESPONSE-REFS>
67
67
  {%- endif%}
68
68
  {%- if service.neg_response_refs %}
69
69
  <NEG-RESPONSE-REFS>
70
70
  {%- for ref in service.neg_response_refs %}
71
- <NEG-RESPONSE-REF ID-REF="{{ref.ref_id}}" />
71
+ <NEG-RESPONSE-REF {{make_ref_attribs(ref)}} />
72
72
  {%- endfor %}
73
73
  </NEG-RESPONSE-REFS>
74
74
  {%- endif%}
@@ -0,0 +1,45 @@
1
+ {#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ -#}
5
+
6
+ {%- import('macros/printChecksum.xml.jinja2') as pcs %}
7
+ {%- import('macros/printElementId.xml.jinja2') as peid %}
8
+ {%- import('macros/printExpectedIdent.xml.jinja2') as pei %}
9
+ {%- import('macros/printSecurity.xml.jinja2') as psec %}
10
+ {%- import('macros/printSpecialData.xml.jinja2') as psd %}
11
+
12
+ {%- macro printSession(session) -%}
13
+ <SESSION {{-peid.printElementIdAttribs(session)|indent(2) }}{# -#}>
14
+ {{ peid.printElementIdSubtags(session)|indent(2) }}
15
+ {%- if session.expected_idents %}
16
+ <EXPECTED-IDENTS>
17
+ {%- for expected_ident in session.expected_idents %}
18
+ {{ pei.printExpectedIdent(expected_ident)|indent(4) }}
19
+ {%- endfor %}
20
+ </EXPECTED-IDENTS>
21
+ {%- endif %}
22
+ {%- if session.checksums %}
23
+ <CHECKSUMS>
24
+ {%- for checksum in session.checksums %}
25
+ {{ pcs.printChecksum(checksum)|indent(4) }}
26
+ {%- endfor %}
27
+ </CHECKSUMS>
28
+ {%- endif %}
29
+ {%- if session.securities %}
30
+ <SECURITYS>
31
+ {%- for security in session.securities %}
32
+ {{ psec.printSecurity(security)|indent(4) }}
33
+ {%- endfor %}
34
+ </SECURITYS>
35
+ {%- endif %}
36
+ {%- if session.datablock_refs %}
37
+ <DATABLOCK-REFS>
38
+ {%- for datablock_ref in session.datablock_refs %}
39
+ <DATABLOCK-REF {{make_ref_attribs(datablock_ref)}} />
40
+ {%- endfor %}
41
+ </DATABLOCK-REFS>
42
+ {%- endif %}
43
+ {{- psd.printSpecialDataGroups(session.sdgs)|indent(2, first=True) }}
44
+ </SESSION>
45
+ {%- endmacro -%}
@@ -0,0 +1,40 @@
1
+ {#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ -#}
5
+
6
+ {%- import('macros/printAudience.xml.jinja2') as paud %}
7
+ {%- import('macros/printElementId.xml.jinja2') as peid %}
8
+ {%- import('macros/printOwnIdent.xml.jinja2') as poid %}
9
+ {%- import('macros/printSpecialData.xml.jinja2') as psd %}
10
+
11
+ {%- macro printSessionDesc(session_desc) -%}
12
+ <SESSION-DESC {#- #} {{- make_xml_attrib("OID", session_desc.oid) -}}
13
+ {#- #} DIRECTION="{{session_desc.direction.value}}">
14
+ {{ peid.printElementIdSubtags(session_desc)}}
15
+ {%- if session_desc.partnumber is not none %}
16
+ <PARTNUMBER>{{session_desc.partnumber}}</PARTNUMBER>
17
+ {%- endif %}
18
+ {%- if session_desc.priority is not none %}
19
+ <PRIORITY>{{session_desc.priority}}</PRIORITY>
20
+ {%- endif %}
21
+ <SESSION-SNREF SHORT-NAME="{{ session_desc.session_snref }}" />
22
+ {%- if session_desc.diag_comm_snref is not none %}
23
+ <DIAG-COMM-SNREF SHORT-NAME="{{ session_desc.diag_comm_snref }}" />
24
+ {%- endif %}
25
+ {%- if session_desc.flash_class_refs %}
26
+ <FLASH-CLASS-REFS>
27
+ {%- for flash_class_ref in session_desc.flash_class_refs %}
28
+ <FLASH-CLASS-REF {{make_ref_attribs(flash_class_ref)}} />
29
+ {%- endfor %}
30
+ </FLASH-CLASS-REFS>
31
+ {%- endif %}
32
+ {{- psd.printSpecialDataGroups(session_desc.sdgs)|indent(2, first=True) }}{#- #}
33
+ {%- if session_desc.audience is not none %}
34
+ {{ paud.printAudience(session_desc.audience) | indent(2) }}
35
+ {%- endif %}
36
+ {%- if session_desc.own_ident is not none %}
37
+ {{poid.printOwnIdent(session_desc.own_ident) | indent(2)}}
38
+ {%- endif %}
39
+ </SESSION-DESC>
40
+ {%- endmacro -%}
@@ -47,7 +47,7 @@
47
47
  {%- if param.physical_default_value is not none %}
48
48
  <PHYSICAL-DEFAULT-VALUE>{{param.physical_default_value | e}}</PHYSICAL-DEFAULT-VALUE>
49
49
  {%- endif %}
50
- <DOP-BASE-REF ID-REF="{{param.dop_base_ref.ref_id}}" />
50
+ <DOP-BASE-REF {{make_ref_attribs(param.dop_base_ref)}} />
51
51
  </INPUT-PARAM>
52
52
  {%- endmacro -%}
53
53
 
@@ -56,7 +56,7 @@
56
56
  {{-make_xml_attrib("OID", param.oid)}}
57
57
  {{-make_xml_attrib("SEMANTIC", param.semantic)}}>
58
58
  {{ peid.printElementIdSubtags(param)|indent(1) }}
59
- <DOP-BASE-REF ID-REF="{{param.dop_base_ref.ref_id}}" />
59
+ <DOP-BASE-REF {{make_ref_attribs(param.dop_base_ref)}} />
60
60
  </OUTPUT-PARAM>
61
61
  {%- endmacro -%}
62
62
 
@@ -64,6 +64,6 @@
64
64
  {%- macro printNegOutputParam(param) -%}
65
65
  <NEG-OUTPUT-PARAM>
66
66
  {{ peid.printElementIdSubtags(param)|indent(1) }}
67
- <DOP-BASE-REF ID-REF="{{param.dop_base_ref.ref_id}}" />
67
+ <DOP-BASE-REF {{make_ref_attribs(param.dop_base_ref)}} />
68
68
  </NEG-OUTPUT-PARAM>
69
69
  {%- endmacro -%}
@@ -25,7 +25,7 @@
25
25
  {%- macro printSpecialDataGroup(sdg) %}
26
26
  <SDG {{-make_xml_attrib("SI", sdg.semantic_info)}}>
27
27
  {%- if sdg.sdg_caption_ref %}
28
- <SDG-CAPTION-REF ID-REF="{{sdg.sdg_caption_ref.ref_id}}" />
28
+ <SDG-CAPTION-REF {{make_ref_attribs(sdg.sdg_caption_ref)}} />
29
29
  {%- elif sdg.sdg_caption %}
30
30
  {{- printSdgCaption(sdg.sdg_caption) | indent(1, first=True) }}
31
31
  {%- endif %}
@@ -49,4 +49,4 @@
49
49
  {%- endfor %}
50
50
  </SDGS>
51
51
  {%- endif %}
52
- {%- endmacro %}
52
+ {#- #}{%- endmacro %}
@@ -4,7 +4,7 @@
4
4
  -#}
5
5
 
6
6
  {%- macro printStateTransitionRef(st_ref) -%}
7
- <STATE-TRANSITION-REF ID-REF="{{st_ref.ref_id}}">
7
+ <STATE-TRANSITION-REF {{make_ref_attribs(st_ref)}}>
8
8
  {%- if st_ref.value is not none %}
9
9
  <VALUE>{{ st_ref.value }}</VALUE>
10
10
  {%- endif %}
@@ -8,7 +8,7 @@
8
8
  {%- macro printStaticField(sf) -%}
9
9
  <STATIC-FIELD {{-peid.printElementIdAttribs(sf)}}>
10
10
  {{ peid.printElementIdSubtags(sf)|indent(1) }}
11
- <BASIC-STRUCTURE-REF ID-REF="{{sf.structure_ref.ref_id}}" />
11
+ <BASIC-STRUCTURE-REF {{make_ref_attribs(sf.structure_ref)}} />
12
12
  <FIXED-NUMBER-OF-ITEMS>{{sf.fixed_number_of_items}}</FIXED-NUMBER-OF-ITEMS>
13
13
  <ITEM-BYTE-SIZE>{{sf.item_byte_size}}</ITEM-BYTE-SIZE>
14
14
  </STATIC-FIELD>
@@ -40,7 +40,7 @@
40
40
  {%- macro printTableRowConnector(conn) %}
41
41
  <TABLE-ROW-CONNECTOR>
42
42
  {{ peid.printElementIdSubtags(conn)|indent(2) }}
43
- <TABLE-REF ID-REF="{{ conn.table_ref.ref_id }}" />
43
+ <TABLE-REF {{make_ref_attribs(conn.table_ref)}} />
44
44
  <TABLE-ROW-SNREF {{- make_xml_attrib("SHORT-NAME", conn.table_row_snref ) }} />
45
45
  </TABLE-ROW-CONNECTOR>
46
46
  {%- endmacro %}
@@ -48,7 +48,7 @@
48
48
  {%- macro printEnvDataConnector(conn) %}
49
49
  <ENV-DATA-CONNECTOR>
50
50
  {{ peid.printElementIdSubtags(conn)|indent(2) }}
51
- <ENV-DATA-DESC-REF ID-REF="{{ conn.env_data_desc_ref.ref_id }}" />
51
+ <ENV-DATA-DESC-REF {{make_ref_attribs(conn.env_data_desc_ref)}} />
52
52
  <ENV-DATA-SNREF {{- make_xml_attrib("SHORT-NAME", conn.env_data_snref ) }} />
53
53
  </ENV-DATA-CONNECTOR>
54
54
  {%- endmacro %}
@@ -56,7 +56,7 @@
56
56
  {%- macro printDtcConnector(conn) %}
57
57
  <DTC-CONNECTOR>
58
58
  {{ peid.printElementIdSubtags(conn)|indent(2) }}
59
- <DTC-DOP-REF ID-REF="{{ conn.dtc_dop_ref.ref_id }}" />
59
+ <DTC-DOP-REF {{make_ref_attribs(conn.dtc_dop_ref)}} />
60
60
  <DOP-SNREF {{- make_xml_attrib("SHORT-NAME", conn.dtc_snref ) }} />
61
61
  </DTC-CONNECTOR>
62
62
  {%- endmacro %}
@@ -16,7 +16,7 @@
16
16
  {{-make_xml_attrib("SEMANTIC", table.semantic)}}>
17
17
  {{ peid.printElementIdSubtags(table)|indent(1) }}
18
18
  {%- if table.key_dop_ref %}
19
- <KEY-DOP-REF ID-REF="{{ table.key_dop_ref.ref_id }}" />
19
+ <KEY-DOP-REF {{make_ref_attribs(table.key_dop_ref)}} />
20
20
  {%- endif %}
21
21
  {%- for table_row in table.table_rows_raw %}
22
22
  {%- if hasattr(table_row, "key") %}
@@ -25,13 +25,13 @@
25
25
  {{-peid.printElementIdSubtags(table_row)}}
26
26
  <KEY>{{table_row.key|e}}</KEY>
27
27
  {%- if table_row.dop_ref is not none %}
28
- <DATA-OBJECT-PROP-REF ID-REF="{{ table_row.dop_ref.ref_id }}" />
28
+ <DATA-OBJECT-PROP-REF {{make_ref_attribs(table_row.dop_ref)}} />
29
29
  {%- endif %}
30
30
  {%- if table_row.dop_snref is not none %}
31
31
  <DATA-OBJECT-PROP-SNREF SHORT-NAME="{{ table_row.dop_snref }}" />
32
32
  {%- endif %}
33
33
  {%- if table_row.structure_ref is not none %}
34
- <STRUCTURE-REF ID-REF="{{ table_row.structure_ref.ref_id }}" />
34
+ <STRUCTURE-REF {{make_ref_attribs(table_row.structure_ref)}} />
35
35
  {%- endif %}
36
36
  {%- if table_row.structure_snref is not none %}
37
37
  <STRUCTURE-SNREF SHORT-NAME="{{ table_row.structure_snref }}" />
@@ -43,7 +43,7 @@
43
43
  {%- if table_row.functional_class_refs %}
44
44
  <FUNCT-CLASS-REFS>
45
45
  {%- for fc_ref in table_row.functional_class_refs %}
46
- <FUNCT-CLASS-REF ID-REF="{{ fc_ref.ref_id }}" />
46
+ <FUNCT-CLASS-REF {{make_ref_attribs(fc_ref)}} />
47
47
  {%- endfor %}
48
48
  </FUNCT-CLASS-REFS>
49
49
  {%- endif %}
@@ -66,7 +66,7 @@
66
66
  {%- endif %}
67
67
  </TABLE-ROW>
68
68
  {%- else %}
69
- <TABLE-ROW-REF ID-REF="{{ table_row.ref_id }}" />
69
+ <TABLE-ROW-REF {{make_ref_attribs(table_row)}} />
70
70
  {%- endif %}
71
71
  {%- endfor %}
72
72
  {%- if table_diag_comm_connectors %}
@@ -75,7 +75,7 @@
75
75
  <TABLE-DIAG-COMM-CONNECTOR>
76
76
  <SEMANTIC>{{tdcc.semantic}}</SEMANTIC>
77
77
  {%- if tdcc.diag_comm_ref %}
78
- <DIAG-COMM-REF ID-REF="{{ tdcc.diag_comm_ref.ref_id }}" />
78
+ <DIAG-COMM-REF {{make_ref_attribs(tdcc.diag_comm_ref)}} />
79
79
  {%- elif tdcc.diag_comm_snref %}
80
80
  <DIAG-COMM-SNREF SHORT-NAME="{{ tdcc.diag_comm_snref }}" />
81
81
  {%- endif %}
@@ -49,7 +49,7 @@
49
49
  <OFFSET-SI-TO-UNIT>{{ unit.offset_si_to_unit }}</OFFSET-SI-TO-UNIT>
50
50
  {%- endif %}
51
51
  {%- if unit.physical_dimension_ref %}
52
- <PHYSICAL-DIMENSION-REF ID-REF="{{ unit.physical_dimension_ref.ref_id }}" />
52
+ <PHYSICAL-DIMENSION-REF {{make_ref_attribs(unit.physical_dimension_ref)}} />
53
53
  {%- endif %}
54
54
  </UNIT>
55
55
  {%- endmacro -%}
@@ -61,7 +61,7 @@
61
61
  {%- if group.unit_refs %}
62
62
  <UNIT-REFS>
63
63
  {%- for ref in group.unit_refs %}
64
- <UNIT-REF ID-REF="{{ ref.ref_id }}" />
64
+ <UNIT-REF {{make_ref_attribs(ref)}} />
65
65
  {%- endfor %}
66
66
  </UNIT-REFS>
67
67
  {%- endif %}
odxtools/text.py CHANGED
@@ -2,6 +2,7 @@ from dataclasses import dataclass
2
2
  from xml.etree import ElementTree
3
3
 
4
4
  from .odxdoccontext import OdxDocContext
5
+ from .utils import strip_indent
5
6
 
6
7
 
7
8
  @dataclass(kw_only=True)
@@ -16,12 +17,7 @@ class Text:
16
17
  for e in et_element:
17
18
  raw_string += ElementTree.tostring(e, encoding="unicode")
18
19
 
19
- # remove white spaces at the beginning and at the end of all
20
- # extracted lines
21
- stripped_lines = [x.strip() for x in raw_string.split("\n")]
22
-
23
- text = "\n".join(stripped_lines).strip()
24
-
20
+ text = strip_indent(raw_string)
25
21
  text_identifier = et_element.get("TI")
26
22
 
27
23
  return Text(text=text, text_identifier=text_identifier)
odxtools/utils.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import dataclasses
3
3
  import re
4
- from typing import TYPE_CHECKING, Any, Optional
4
+ from typing import TYPE_CHECKING, Any, Optional, overload
5
5
  from xml.etree import ElementTree
6
6
 
7
7
  from .exceptions import odxraise
@@ -12,6 +12,27 @@ if TYPE_CHECKING:
12
12
  from .snrefcontext import SnRefContext
13
13
 
14
14
 
15
+ @overload
16
+ def strip_indent(text: str) -> str:
17
+ ...
18
+
19
+
20
+ @overload
21
+ def strip_indent(text: None) -> None:
22
+ ...
23
+
24
+
25
+ def strip_indent(text: str | None) -> str | None:
26
+ """Remove the leading and trailing space characters of all lines of a string.
27
+
28
+ Note that non-space whitespace characters (tabulators, etc) are unaffected
29
+ """
30
+ if text is None:
31
+ return None
32
+
33
+ return "\n".join([x.strip(" \r") for x in text.split("\n")])
34
+
35
+
15
36
  def read_hex_binary(et_element: ElementTree.Element | None) -> int | None:
16
37
  """Convert the contents of an xsd:hexBinary to an integer
17
38
  """
@@ -0,0 +1,30 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass
3
+ from typing import cast
4
+ from xml.etree import ElementTree
5
+
6
+ from .exceptions import odxraise, odxrequire
7
+ from .odxdoccontext import OdxDocContext
8
+ from .sessionsubelemtype import SessionSubElemType
9
+
10
+
11
+ @dataclass(kw_only=True)
12
+ class ValidityFor:
13
+ value: str
14
+ value_type: SessionSubElemType
15
+
16
+ @staticmethod
17
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ValidityFor":
18
+ value = et_element.text or ""
19
+
20
+ value_type_str = odxrequire(et_element.get("TYPE"))
21
+ try:
22
+ value_type = SessionSubElemType(value_type_str)
23
+ except ValueError:
24
+ value_type = cast(SessionSubElemType, None)
25
+ odxraise(f"Encountered unknown SESSION-SUB-ELEM-TYPE type '{value_type_str}'")
26
+
27
+ return ValidityFor(
28
+ value=value,
29
+ value_type=value_type,
30
+ )
odxtools/version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '10.1.0'
21
- __version_tuple__ = version_tuple = (10, 1, 0)
20
+ __version__ = version = '10.2.0'
21
+ __version_tuple__ = version_tuple = (10, 2, 0)