powertrain-build 1.13.1__py3-none-any.whl → 1.13.3.dev3__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 (132) hide show
  1. powertrain_build/__init__.py +40 -40
  2. powertrain_build/__main__.py +6 -6
  3. powertrain_build/a2l.py +582 -582
  4. powertrain_build/a2l_merge.py +650 -650
  5. powertrain_build/a2l_templates.py +717 -717
  6. powertrain_build/build.py +985 -985
  7. powertrain_build/build_defs.py +309 -309
  8. powertrain_build/build_proj_config.py +690 -690
  9. powertrain_build/check_interface.py +575 -575
  10. powertrain_build/cli.py +141 -141
  11. powertrain_build/config.py +542 -542
  12. powertrain_build/core.py +395 -395
  13. powertrain_build/core_dummy.py +343 -343
  14. powertrain_build/create_conversion_table.py +73 -73
  15. powertrain_build/dids.py +916 -916
  16. powertrain_build/dummy.py +157 -157
  17. powertrain_build/dummy_spm.py +252 -252
  18. powertrain_build/environmentcheck.py +52 -52
  19. powertrain_build/ext_dbg.py +255 -255
  20. powertrain_build/ext_var.py +327 -327
  21. powertrain_build/feature_configs.py +301 -301
  22. powertrain_build/gen_allsysteminfo.py +227 -227
  23. powertrain_build/gen_label_split.py +449 -449
  24. powertrain_build/handcode_replacer.py +124 -124
  25. powertrain_build/html_report.py +133 -133
  26. powertrain_build/interface/__init__.py +4 -4
  27. powertrain_build/interface/application.py +511 -511
  28. powertrain_build/interface/base.py +500 -500
  29. powertrain_build/interface/csp_api.py +490 -490
  30. powertrain_build/interface/device_proxy.py +677 -677
  31. powertrain_build/interface/ems.py +67 -67
  32. powertrain_build/interface/export_global_vars.py +121 -121
  33. powertrain_build/interface/generate_adapters.py +132 -132
  34. powertrain_build/interface/generate_hi_interface.py +87 -87
  35. powertrain_build/interface/generate_service.py +69 -69
  36. powertrain_build/interface/generate_wrappers.py +147 -147
  37. powertrain_build/interface/generation_utils.py +142 -142
  38. powertrain_build/interface/hal.py +194 -194
  39. powertrain_build/interface/model_yaml_verification.py +348 -348
  40. powertrain_build/interface/service.py +296 -296
  41. powertrain_build/interface/simulink.py +249 -249
  42. powertrain_build/interface/update_call_sources.py +180 -180
  43. powertrain_build/interface/update_model_yaml.py +186 -186
  44. powertrain_build/interface/zone_controller.py +362 -362
  45. powertrain_build/lib/__init__.py +4 -4
  46. powertrain_build/lib/helper_functions.py +127 -127
  47. powertrain_build/lib/logger.py +55 -55
  48. powertrain_build/matlab_scripts/CodeGen/BuildAutomationPyBuild.m +78 -78
  49. powertrain_build/matlab_scripts/CodeGen/Generate_A2L.m +154 -154
  50. powertrain_build/matlab_scripts/CodeGen/generateTLUnit.m +239 -239
  51. powertrain_build/matlab_scripts/CodeGen/getAsilClassification.m +28 -28
  52. powertrain_build/matlab_scripts/CodeGen/modelConfiguredForTL.m +28 -28
  53. powertrain_build/matlab_scripts/CodeGen/moveDefOutports.m +88 -88
  54. powertrain_build/matlab_scripts/CodeGen/parseCalMeasData.m +410 -410
  55. powertrain_build/matlab_scripts/CodeGen/parseCoreIdentifiers.m +139 -139
  56. powertrain_build/matlab_scripts/CodeGen/parseDIDs.m +141 -141
  57. powertrain_build/matlab_scripts/CodeGen/parseInPorts.m +106 -106
  58. powertrain_build/matlab_scripts/CodeGen/parseIncludeConfigs.m +25 -25
  59. powertrain_build/matlab_scripts/CodeGen/parseModelInfo.m +38 -38
  60. powertrain_build/matlab_scripts/CodeGen/parseNVM.m +81 -81
  61. powertrain_build/matlab_scripts/CodeGen/parseOutPorts.m +120 -120
  62. powertrain_build/matlab_scripts/CodeGen/parsePreProcBlks.m +23 -23
  63. powertrain_build/matlab_scripts/CodeGen/struct2JSON.m +128 -128
  64. powertrain_build/matlab_scripts/CodeGen/updateCodeSwConfig.m +31 -31
  65. powertrain_build/matlab_scripts/Init_PyBuild.m +91 -91
  66. powertrain_build/matlab_scripts/__init__.py +2 -2
  67. powertrain_build/matlab_scripts/helperFunctions/Get_Full_Name.m +46 -46
  68. powertrain_build/matlab_scripts/helperFunctions/Get_SrcLines.m +12 -12
  69. powertrain_build/matlab_scripts/helperFunctions/Init_Models.m +78 -78
  70. powertrain_build/matlab_scripts/helperFunctions/Init_Projects.m +67 -67
  71. powertrain_build/matlab_scripts/helperFunctions/Read_Units.m +34 -34
  72. powertrain_build/matlab_scripts/helperFunctions/SetProjectTimeSamples.m +26 -26
  73. powertrain_build/matlab_scripts/helperFunctions/Strip_Suffix.m +16 -16
  74. powertrain_build/matlab_scripts/helperFunctions/followLink.m +118 -118
  75. powertrain_build/matlab_scripts/helperFunctions/getCodeSwitches.m +50 -50
  76. powertrain_build/matlab_scripts/helperFunctions/getConsumerBlocks.m +30 -30
  77. powertrain_build/matlab_scripts/helperFunctions/getDefBlock.m +39 -39
  78. powertrain_build/matlab_scripts/helperFunctions/getDefOutport.m +58 -58
  79. powertrain_build/matlab_scripts/helperFunctions/getDstBlocks.m +19 -19
  80. powertrain_build/matlab_scripts/helperFunctions/getDstLines.m +13 -13
  81. powertrain_build/matlab_scripts/helperFunctions/getInterfaceSignals.m +37 -37
  82. powertrain_build/matlab_scripts/helperFunctions/getName.m +37 -37
  83. powertrain_build/matlab_scripts/helperFunctions/getPath.m +6 -6
  84. powertrain_build/matlab_scripts/helperFunctions/getProperValue.m +21 -21
  85. powertrain_build/matlab_scripts/helperFunctions/getSrcBlocks.m +19 -19
  86. powertrain_build/matlab_scripts/helperFunctions/getSrcLines.m +13 -13
  87. powertrain_build/matlab_scripts/helperFunctions/loadLibraries.m +10 -10
  88. powertrain_build/matlab_scripts/helperFunctions/loadjson.m +6 -6
  89. powertrain_build/matlab_scripts/helperFunctions/modifyEnumStructField.m +21 -21
  90. powertrain_build/matlab_scripts/helperFunctions/removeConfigDuplicates.m +31 -31
  91. powertrain_build/matlab_scripts/helperFunctions/sortSystemByClass.m +26 -26
  92. powertrain_build/matlab_scripts/helperFunctions/tl_getfast.m +89 -89
  93. powertrain_build/matlab_scripts/helperFunctions/topLevelSystem.m +20 -20
  94. powertrain_build/matlab_scripts/helperFunctions/updateModels.m +131 -131
  95. powertrain_build/memory_section.py +224 -224
  96. powertrain_build/nvm_def.py +729 -729
  97. powertrain_build/problem_logger.py +86 -86
  98. powertrain_build/pt_matlab.py +430 -430
  99. powertrain_build/pt_win32.py +144 -144
  100. powertrain_build/replace_compu_tab_ref.py +105 -105
  101. powertrain_build/rte_dummy.py +254 -254
  102. powertrain_build/sched_funcs.py +209 -207
  103. powertrain_build/signal.py +7 -7
  104. powertrain_build/signal_if_html_rep.py +221 -221
  105. powertrain_build/signal_if_html_rep_all.py +302 -302
  106. powertrain_build/signal_incons_html_rep.py +180 -180
  107. powertrain_build/signal_incons_html_rep_all.py +366 -366
  108. powertrain_build/signal_incons_html_rep_base.py +168 -168
  109. powertrain_build/signal_inconsistency_check.py +641 -641
  110. powertrain_build/signal_interfaces.py +864 -864
  111. powertrain_build/templates/Index_SigCheck_All.html +22 -22
  112. powertrain_build/templates/Index_SigIf_All.html +19 -19
  113. powertrain_build/types.py +218 -218
  114. powertrain_build/unit_configs.py +419 -419
  115. powertrain_build/user_defined_types.py +660 -660
  116. powertrain_build/versioncheck.py +66 -66
  117. powertrain_build/wrapper.py +512 -512
  118. powertrain_build/xlrd_csv.py +87 -87
  119. powertrain_build/zone_controller/__init__.py +4 -4
  120. powertrain_build/zone_controller/calibration.py +176 -176
  121. powertrain_build/zone_controller/composition_yaml.py +880 -878
  122. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/METADATA +100 -100
  123. powertrain_build-1.13.3.dev3.dist-info/RECORD +130 -0
  124. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/WHEEL +1 -1
  125. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/licenses/LICENSE +202 -202
  126. powertrain_build-1.13.3.dev3.dist-info/pbr.json +1 -0
  127. powertrain_build-1.13.1.dist-info/RECORD +0 -130
  128. powertrain_build-1.13.1.dist-info/pbr.json +0 -1
  129. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/entry_points.txt +0 -0
  130. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/licenses/AUTHORS +0 -0
  131. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/licenses/NOTICE +0 -0
  132. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/top_level.txt +0 -0
@@ -1,144 +1,144 @@
1
- # Copyright 2024 Volvo Car Corporation
2
- # Licensed under Apache 2.0.
3
-
4
- """Wrapper for win32api to simplify it's use.
5
-
6
- See pywin32 documentation or windows api documentation for more information.
7
- """
8
-
9
- from powertrain_build.lib.helper_functions import merge_dicts
10
-
11
- STILL_ACTIVE = 259
12
-
13
- try:
14
- import win32job
15
- import win32process
16
-
17
- class PtWin32Process:
18
- """Alternative to python subprocess.
19
-
20
- This adds functionality to add processes to win32 job containers
21
- to force processes to terminate after it's parent process dies.
22
- """
23
-
24
- def __init__(self, kill_on_job_close=True):
25
- """Set up default values.
26
-
27
- arguments:
28
- kill_on_job_close (boolean): If True the process will be terminated when all job
29
- handles are closed.
30
- """
31
- self.process_handle = None
32
- self.thread_handle = None
33
- self.job_handle = None
34
- self.process_id = None
35
- self.thread_id = None
36
- self.process_attributes = None
37
- self.thread_attributes = None
38
- self.b_inherit_handles = True
39
- self.dw_creation_flags = 0
40
- self.new_environment = None
41
- self.current_directory = None
42
- self.job_limit_flag_list = []
43
- self.startup_info = win32process.STARTUPINFO()
44
- self.limit_info_dict = {"BasicLimitInformation": {"LimitFlags": 0}}
45
-
46
- if kill_on_job_close:
47
- self.add_limit_flags(win32job.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE)
48
-
49
- def run(self, app_name=None, command=None):
50
- """Run process.
51
-
52
- Can be run with either a specified application, a command line string or both.
53
-
54
- Keyword arguments:
55
- app_name (string): path to application to execute.
56
- command (string): command line string to use in execution.
57
- """
58
- self.process_handle, self.thread_handle, self.process_id, self.thread_id = win32process.CreateProcess(
59
- app_name,
60
- command,
61
- self.process_attributes,
62
- self.thread_attributes,
63
- self.b_inherit_handles,
64
- self.dw_creation_flags,
65
- self.new_environment,
66
- self.current_directory,
67
- self.startup_info,
68
- )
69
-
70
- self.job_handle = win32job.CreateJobObject(None, "")
71
- limit_information = self.get_extended_limit_information()
72
- limit_information = merge_dicts(self.limit_info_dict, limit_information, merge_recursively=True)
73
- win32job.SetInformationJobObject(
74
- self.job_handle, win32job.JobObjectExtendedLimitInformation, limit_information
75
- )
76
- win32job.AssignProcessToJobObject(self.job_handle, self.process_handle)
77
-
78
- def get_extended_limit_information(self):
79
- """Get extended limit information."""
80
- return win32job.QueryInformationJobObject(self.job_handle, win32job.JobObjectExtendedLimitInformation)
81
-
82
- def set_current_directory(self, current_directory):
83
- """Set process working directory."""
84
- self.current_directory = current_directory
85
-
86
- def set_environment(self, environment):
87
- """Set process environment variables.
88
-
89
- If not set the process will inherit parent process environment.
90
-
91
- arguments:
92
- environment (dict): a dictionary with environment variables to be set.
93
- """
94
- self.new_environment = environment
95
-
96
- def set_creation_flags(self, creation_flags):
97
- """Set creation flags.
98
-
99
- arguments:
100
- creation_flags (int): See pywin32 documentation or windows api for documentation.
101
- """
102
- self.dw_creation_flags = creation_flags
103
-
104
- def add_limit_flags(self, limit_flags):
105
- """Add limit flag."""
106
- new_limit_flags = self.get_limit_flags() | limit_flags
107
- self.set_limit_flags(new_limit_flags)
108
-
109
- def remove_limit_flags(self, limit_flags):
110
- """Remove limit flag."""
111
- new_limit_flags = self.get_limit_flags() & ~limit_flags
112
- self.set_limit_flags(new_limit_flags)
113
-
114
- def get_limit_flags(self):
115
- """Get limit flags."""
116
- return self.limit_info_dict["BasicLimitInformation"]["LimitFlags"]
117
-
118
- def set_limit_flags(self, win32job_limit):
119
- """Set limit flags.
120
-
121
- arguments:
122
- win32job_limit (int): See pywin32 documentation or windows api documentation.
123
- """
124
- self.limit_info_dict.update({"BasicLimitInformation": {"LimitFlags": win32job_limit}})
125
-
126
- def poll(self):
127
- """Return process status.
128
-
129
- If process is still running it will return exitcode 259 (STILL_ACTIVE).
130
- """
131
- return win32process.GetExitCodeProcess(self.process_handle)
132
-
133
- def terminate(self):
134
- """Terminate all processes associated with the job."""
135
- return win32job.TerminateJobObject(self.job_handle)
136
-
137
- except ImportError:
138
-
139
- class PtWin32Process:
140
- """Dummy."""
141
-
142
- def __init__(self, kill_on_job_close=True):
143
- """Dummy."""
144
- raise OSError("pywin32 is not installed or is not compatible with this platform")
1
+ # Copyright 2024 Volvo Car Corporation
2
+ # Licensed under Apache 2.0.
3
+
4
+ """Wrapper for win32api to simplify it's use.
5
+
6
+ See pywin32 documentation or windows api documentation for more information.
7
+ """
8
+
9
+ from powertrain_build.lib.helper_functions import merge_dicts
10
+
11
+ STILL_ACTIVE = 259
12
+
13
+ try:
14
+ import win32job
15
+ import win32process
16
+
17
+ class PtWin32Process:
18
+ """Alternative to python subprocess.
19
+
20
+ This adds functionality to add processes to win32 job containers
21
+ to force processes to terminate after it's parent process dies.
22
+ """
23
+
24
+ def __init__(self, kill_on_job_close=True):
25
+ """Set up default values.
26
+
27
+ arguments:
28
+ kill_on_job_close (boolean): If True the process will be terminated when all job
29
+ handles are closed.
30
+ """
31
+ self.process_handle = None
32
+ self.thread_handle = None
33
+ self.job_handle = None
34
+ self.process_id = None
35
+ self.thread_id = None
36
+ self.process_attributes = None
37
+ self.thread_attributes = None
38
+ self.b_inherit_handles = True
39
+ self.dw_creation_flags = 0
40
+ self.new_environment = None
41
+ self.current_directory = None
42
+ self.job_limit_flag_list = []
43
+ self.startup_info = win32process.STARTUPINFO()
44
+ self.limit_info_dict = {"BasicLimitInformation": {"LimitFlags": 0}}
45
+
46
+ if kill_on_job_close:
47
+ self.add_limit_flags(win32job.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE)
48
+
49
+ def run(self, app_name=None, command=None):
50
+ """Run process.
51
+
52
+ Can be run with either a specified application, a command line string or both.
53
+
54
+ Keyword arguments:
55
+ app_name (string): path to application to execute.
56
+ command (string): command line string to use in execution.
57
+ """
58
+ self.process_handle, self.thread_handle, self.process_id, self.thread_id = win32process.CreateProcess(
59
+ app_name,
60
+ command,
61
+ self.process_attributes,
62
+ self.thread_attributes,
63
+ self.b_inherit_handles,
64
+ self.dw_creation_flags,
65
+ self.new_environment,
66
+ self.current_directory,
67
+ self.startup_info,
68
+ )
69
+
70
+ self.job_handle = win32job.CreateJobObject(None, "")
71
+ limit_information = self.get_extended_limit_information()
72
+ limit_information = merge_dicts(self.limit_info_dict, limit_information, merge_recursively=True)
73
+ win32job.SetInformationJobObject(
74
+ self.job_handle, win32job.JobObjectExtendedLimitInformation, limit_information
75
+ )
76
+ win32job.AssignProcessToJobObject(self.job_handle, self.process_handle)
77
+
78
+ def get_extended_limit_information(self):
79
+ """Get extended limit information."""
80
+ return win32job.QueryInformationJobObject(self.job_handle, win32job.JobObjectExtendedLimitInformation)
81
+
82
+ def set_current_directory(self, current_directory):
83
+ """Set process working directory."""
84
+ self.current_directory = current_directory
85
+
86
+ def set_environment(self, environment):
87
+ """Set process environment variables.
88
+
89
+ If not set the process will inherit parent process environment.
90
+
91
+ arguments:
92
+ environment (dict): a dictionary with environment variables to be set.
93
+ """
94
+ self.new_environment = environment
95
+
96
+ def set_creation_flags(self, creation_flags):
97
+ """Set creation flags.
98
+
99
+ arguments:
100
+ creation_flags (int): See pywin32 documentation or windows api for documentation.
101
+ """
102
+ self.dw_creation_flags = creation_flags
103
+
104
+ def add_limit_flags(self, limit_flags):
105
+ """Add limit flag."""
106
+ new_limit_flags = self.get_limit_flags() | limit_flags
107
+ self.set_limit_flags(new_limit_flags)
108
+
109
+ def remove_limit_flags(self, limit_flags):
110
+ """Remove limit flag."""
111
+ new_limit_flags = self.get_limit_flags() & ~limit_flags
112
+ self.set_limit_flags(new_limit_flags)
113
+
114
+ def get_limit_flags(self):
115
+ """Get limit flags."""
116
+ return self.limit_info_dict["BasicLimitInformation"]["LimitFlags"]
117
+
118
+ def set_limit_flags(self, win32job_limit):
119
+ """Set limit flags.
120
+
121
+ arguments:
122
+ win32job_limit (int): See pywin32 documentation or windows api documentation.
123
+ """
124
+ self.limit_info_dict.update({"BasicLimitInformation": {"LimitFlags": win32job_limit}})
125
+
126
+ def poll(self):
127
+ """Return process status.
128
+
129
+ If process is still running it will return exitcode 259 (STILL_ACTIVE).
130
+ """
131
+ return win32process.GetExitCodeProcess(self.process_handle)
132
+
133
+ def terminate(self):
134
+ """Terminate all processes associated with the job."""
135
+ return win32job.TerminateJobObject(self.job_handle)
136
+
137
+ except ImportError:
138
+
139
+ class PtWin32Process:
140
+ """Dummy."""
141
+
142
+ def __init__(self, kill_on_job_close=True):
143
+ """Dummy."""
144
+ raise OSError("pywin32 is not installed or is not compatible with this platform")
@@ -1,105 +1,105 @@
1
- # Copyright 2024 Volvo Car Corporation
2
- # Licensed under Apache 2.0.
3
-
4
- """Module for replacing $CVC_* style references in a2l file."""
5
-
6
- import argparse
7
- import re
8
- import sys
9
- from pathlib import Path
10
- from typing import List, Optional
11
-
12
-
13
- PARSER_HELP = "Replace $CVC_* style references in a2l file"
14
-
15
-
16
- def configure_parser(parser: argparse.ArgumentParser):
17
- """Configure parser for CLI."""
18
- parser.add_argument("a2l_target_file")
19
- parser.set_defaults(func=replace_tab_verb_cli)
20
-
21
-
22
- def replace_tab_verb_cli(args: argparse.Namespace):
23
- """CLI wrapper function for passing in Namespace object.
24
-
25
- This allows maintaining a standardized CLI function signature while not breaking backwards
26
- compatibility with replace_tab_verb.
27
- """
28
- replace_tab_verb(args.a2l_target_file)
29
-
30
-
31
- def replace_tab_verb(file_path: Path):
32
- """Replace custom Units with conversion table."""
33
- with open(file_path, encoding='ISO-8859-1') as f_h:
34
- a2l_text = f_h.read()
35
-
36
- ##############################################################
37
- # Absolutely horrible multi-line regex #
38
- # #
39
- # Translates a fake COMPU_METHOD #
40
- # with custom $CVC_* Unit into using a conversion table #
41
- # #
42
- ##############################################################
43
- # If a dollar is found make the following changes: #
44
- # 'RAT_FUNC' => 'TAB_VERB' #
45
- # 'LINEAR' => 'TAB_VERB' #
46
- # New format => "%12.6" #
47
- # Save the $-tag and remove it from the unit #
48
- # Change the line below the '/* Unit */'- line to #
49
- # "['COMPU_TAB_REF CONV_TAB_' $-tag] #
50
- ##############################################################
51
- # ***************************BEFORE************************* #
52
- ##############################################################
53
- # /begin COMPU_METHOD #
54
- # VcDummy_spm_1_0_0_None__CVC_EmCoBaseMode /* Name */ #
55
- # "" /* LongIdentifier */ #
56
- # RAT_FUNC /* ConversionType */ #
57
- # "%11.3" /* Format */ #
58
- # "-,$CVC_EmCoBaseMode" /* Unit */ #
59
- # COEFFS 0 1 0.0 0 0 1 #
60
- # /end COMPU_METHOD #
61
- ##############################################################
62
- # ***************************AFTER************************** #
63
- ##############################################################
64
- # /begin COMPU_METHOD #
65
- # VcDummy_spm_1_0_0_None__CVC_EmCoBaseMode /* Name */ #
66
- # "" /* LongIdentifier */ #
67
- # TAB_VERB /* ConversionType */ #
68
- # "%12.6" /* Format */ #
69
- # "-" /* Unit */ #
70
- # COMPU_TAB_REF CONV_TAB_CVC_EmCoBaseMode #
71
- # /end COMPU_METHOD #
72
- ##############################################################
73
-
74
- COMPU_METHOD_EXPRESSION = (
75
- r"(RAT_FUNC|LINEAR)" # Match conversion types RAT_FUNC or LINEAR
76
- r"(?P<conv_type_end>\s+/\* ConversionType \*/\n)" # Capture end of conversion type line
77
- r'(?P<format_begin>\s+"%)' # Capture beginning of format line
78
- r"[0-9]+[.][0-9]+" # Capture formatting
79
- r'(?P<format_end>"\s+/\* Format \*/\n)' # Capture end format line
80
- r'(?P<unit_begin>\s+"[\sA-Za-z0-9\-_/]+)' # Capture beginning of unit line
81
- r",\$(?P<tab_verb>CVC_[A-Za-z0-9_]+)" # Capture tab_verb 'CVC_*' of $CVC_EmCoBaseMode
82
- r'(?P<unit_end>"\s*/\* Unit \*/\n)' # Capture end of unit line
83
- r"\s+COEFFS( \d+(.\d+)?)+"
84
- ) # Capture COEFFS line
85
- COMPU_METHOD_REGEX = re.compile(COMPU_METHOD_EXPRESSION)
86
- TAB_VERB_REPLACE = (
87
- r"TAB_VERB\g<conv_type_end>\g<format_begin>12.6\g<format_end>\g<unit_begin>\g<unit_end>"
88
- r" COMPU_TAB_REF CONV_TAB_\g<tab_verb>"
89
- )
90
-
91
- a2l_patched = COMPU_METHOD_REGEX.sub(TAB_VERB_REPLACE, a2l_text)
92
- with open(file_path, "w") as f_h:
93
- f_h.write(a2l_patched)
94
-
95
-
96
- def main(argv: Optional[List[str]] = None):
97
- """Main function for CLI."""
98
- parser = argparse.ArgumentParser(description=PARSER_HELP)
99
- configure_parser(parser)
100
- args = parser.parse_args(argv)
101
- args.func(args)
102
-
103
-
104
- if __name__ == "__main__":
105
- main(sys.argv[1:])
1
+ # Copyright 2024 Volvo Car Corporation
2
+ # Licensed under Apache 2.0.
3
+
4
+ """Module for replacing $CVC_* style references in a2l file."""
5
+
6
+ import argparse
7
+ import re
8
+ import sys
9
+ from pathlib import Path
10
+ from typing import List, Optional
11
+
12
+
13
+ PARSER_HELP = "Replace $CVC_* style references in a2l file"
14
+
15
+
16
+ def configure_parser(parser: argparse.ArgumentParser):
17
+ """Configure parser for CLI."""
18
+ parser.add_argument("a2l_target_file")
19
+ parser.set_defaults(func=replace_tab_verb_cli)
20
+
21
+
22
+ def replace_tab_verb_cli(args: argparse.Namespace):
23
+ """CLI wrapper function for passing in Namespace object.
24
+
25
+ This allows maintaining a standardized CLI function signature while not breaking backwards
26
+ compatibility with replace_tab_verb.
27
+ """
28
+ replace_tab_verb(args.a2l_target_file)
29
+
30
+
31
+ def replace_tab_verb(file_path: Path):
32
+ """Replace custom Units with conversion table."""
33
+ with open(file_path, encoding='ISO-8859-1') as f_h:
34
+ a2l_text = f_h.read()
35
+
36
+ ##############################################################
37
+ # Absolutely horrible multi-line regex #
38
+ # #
39
+ # Translates a fake COMPU_METHOD #
40
+ # with custom $CVC_* Unit into using a conversion table #
41
+ # #
42
+ ##############################################################
43
+ # If a dollar is found make the following changes: #
44
+ # 'RAT_FUNC' => 'TAB_VERB' #
45
+ # 'LINEAR' => 'TAB_VERB' #
46
+ # New format => "%12.6" #
47
+ # Save the $-tag and remove it from the unit #
48
+ # Change the line below the '/* Unit */'- line to #
49
+ # "['COMPU_TAB_REF CONV_TAB_' $-tag] #
50
+ ##############################################################
51
+ # ***************************BEFORE************************* #
52
+ ##############################################################
53
+ # /begin COMPU_METHOD #
54
+ # VcDummy_spm_1_0_0_None__CVC_EmCoBaseMode /* Name */ #
55
+ # "" /* LongIdentifier */ #
56
+ # RAT_FUNC /* ConversionType */ #
57
+ # "%11.3" /* Format */ #
58
+ # "-,$CVC_EmCoBaseMode" /* Unit */ #
59
+ # COEFFS 0 1 0.0 0 0 1 #
60
+ # /end COMPU_METHOD #
61
+ ##############################################################
62
+ # ***************************AFTER************************** #
63
+ ##############################################################
64
+ # /begin COMPU_METHOD #
65
+ # VcDummy_spm_1_0_0_None__CVC_EmCoBaseMode /* Name */ #
66
+ # "" /* LongIdentifier */ #
67
+ # TAB_VERB /* ConversionType */ #
68
+ # "%12.6" /* Format */ #
69
+ # "-" /* Unit */ #
70
+ # COMPU_TAB_REF CONV_TAB_CVC_EmCoBaseMode #
71
+ # /end COMPU_METHOD #
72
+ ##############################################################
73
+
74
+ COMPU_METHOD_EXPRESSION = (
75
+ r"(RAT_FUNC|LINEAR)" # Match conversion types RAT_FUNC or LINEAR
76
+ r"(?P<conv_type_end>\s+/\* ConversionType \*/\n)" # Capture end of conversion type line
77
+ r'(?P<format_begin>\s+"%)' # Capture beginning of format line
78
+ r"[0-9]+[.][0-9]+" # Capture formatting
79
+ r'(?P<format_end>"\s+/\* Format \*/\n)' # Capture end format line
80
+ r'(?P<unit_begin>\s+"[\sA-Za-z0-9\-_/]+)' # Capture beginning of unit line
81
+ r",\$(?P<tab_verb>CVC_[A-Za-z0-9_]+)" # Capture tab_verb 'CVC_*' of $CVC_EmCoBaseMode
82
+ r'(?P<unit_end>"\s*/\* Unit \*/\n)' # Capture end of unit line
83
+ r"\s+COEFFS( \d+(.\d+)?)+"
84
+ ) # Capture COEFFS line
85
+ COMPU_METHOD_REGEX = re.compile(COMPU_METHOD_EXPRESSION)
86
+ TAB_VERB_REPLACE = (
87
+ r"TAB_VERB\g<conv_type_end>\g<format_begin>12.6\g<format_end>\g<unit_begin>\g<unit_end>"
88
+ r" COMPU_TAB_REF CONV_TAB_\g<tab_verb>"
89
+ )
90
+
91
+ a2l_patched = COMPU_METHOD_REGEX.sub(TAB_VERB_REPLACE, a2l_text)
92
+ with open(file_path, "w") as f_h:
93
+ f_h.write(a2l_patched)
94
+
95
+
96
+ def main(argv: Optional[List[str]] = None):
97
+ """Main function for CLI."""
98
+ parser = argparse.ArgumentParser(description=PARSER_HELP)
99
+ configure_parser(parser)
100
+ args = parser.parse_args(argv)
101
+ args.func(args)
102
+
103
+
104
+ if __name__ == "__main__":
105
+ main(sys.argv[1:])