autosar-calltree 0.3.2__py3-none-any.whl → 0.4.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.
- autosar_calltree/cli/main.py +39 -2
- autosar_calltree/generators/__init__.py +2 -1
- autosar_calltree/generators/xmi_generator.py +357 -0
- autosar_calltree/parsers/c_parser.py +33 -0
- autosar_calltree/version.py +1 -1
- {autosar_calltree-0.3.2.dist-info → autosar_calltree-0.4.0.dist-info}/METADATA +2 -2
- {autosar_calltree-0.3.2.dist-info → autosar_calltree-0.4.0.dist-info}/RECORD +11 -10
- {autosar_calltree-0.3.2.dist-info → autosar_calltree-0.4.0.dist-info}/WHEEL +0 -0
- {autosar_calltree-0.3.2.dist-info → autosar_calltree-0.4.0.dist-info}/entry_points.txt +0 -0
- {autosar_calltree-0.3.2.dist-info → autosar_calltree-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {autosar_calltree-0.3.2.dist-info → autosar_calltree-0.4.0.dist-info}/top_level.txt +0 -0
autosar_calltree/cli/main.py
CHANGED
|
@@ -17,6 +17,7 @@ from ..analyzers.call_tree_builder import CallTreeBuilder
|
|
|
17
17
|
from ..config.module_config import ModuleConfig
|
|
18
18
|
from ..database.function_database import FunctionDatabase
|
|
19
19
|
from ..generators.mermaid_generator import MermaidGenerator
|
|
20
|
+
from ..generators.xmi_generator import XmiGenerator
|
|
20
21
|
from ..version import __version__
|
|
21
22
|
|
|
22
23
|
console = Console(record=True)
|
|
@@ -295,11 +296,47 @@ def cli(
|
|
|
295
296
|
)
|
|
296
297
|
|
|
297
298
|
if format == "xmi":
|
|
298
|
-
|
|
299
|
+
with Progress(
|
|
300
|
+
SpinnerColumn(),
|
|
301
|
+
TextColumn("[progress.description]{task.description}"),
|
|
302
|
+
console=console,
|
|
303
|
+
transient=True,
|
|
304
|
+
) as progress:
|
|
305
|
+
task = progress.add_task("Generating XMI document...", total=None)
|
|
306
|
+
|
|
307
|
+
xmi_output = output_path.with_suffix(".xmi") if output_path.suffix != ".xmi" else output_path
|
|
308
|
+
|
|
309
|
+
xmi_generator = XmiGenerator(
|
|
310
|
+
use_module_names=use_module_names,
|
|
311
|
+
)
|
|
312
|
+
xmi_generator.generate(result, str(xmi_output))
|
|
313
|
+
|
|
314
|
+
progress.update(task, completed=True)
|
|
315
|
+
|
|
316
|
+
console.print(
|
|
317
|
+
f"[green]Generated[/green] XMI document: [cyan]{xmi_output}[/cyan]"
|
|
318
|
+
)
|
|
299
319
|
|
|
300
320
|
if format == "both":
|
|
321
|
+
with Progress(
|
|
322
|
+
SpinnerColumn(),
|
|
323
|
+
TextColumn("[progress.description]{task.description}"),
|
|
324
|
+
console=console,
|
|
325
|
+
transient=True,
|
|
326
|
+
) as progress:
|
|
327
|
+
task = progress.add_task("Generating XMI document...", total=None)
|
|
328
|
+
|
|
329
|
+
xmi_output = output_path.with_suffix(".xmi")
|
|
330
|
+
|
|
331
|
+
xmi_generator = XmiGenerator(
|
|
332
|
+
use_module_names=use_module_names,
|
|
333
|
+
)
|
|
334
|
+
xmi_generator.generate(result, str(xmi_output))
|
|
335
|
+
|
|
336
|
+
progress.update(task, completed=True)
|
|
337
|
+
|
|
301
338
|
console.print(
|
|
302
|
-
"[
|
|
339
|
+
f"[green]Generated[/green] XMI document: [cyan]{xmi_output}[/cyan]"
|
|
303
340
|
)
|
|
304
341
|
|
|
305
342
|
# Print warnings for circular dependencies
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
"""
|
|
2
|
+
XMI (XML Metadata Interchange) generator for UML sequence diagrams.
|
|
3
|
+
|
|
4
|
+
This module generates XMI 2.5 compliant XML documents representing
|
|
5
|
+
UML sequence diagrams from call trees. The XMI format can be imported
|
|
6
|
+
into UML tools like Enterprise Architect, Visual Paradigm, etc.
|
|
7
|
+
|
|
8
|
+
Requirements:
|
|
9
|
+
- SWR_XMI_00001: XMI 2.5 Compliance
|
|
10
|
+
- SWR_XMI_00002: Sequence Diagram Representation
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Dict, List, Optional
|
|
15
|
+
from xml.dom import minidom
|
|
16
|
+
from xml.etree.ElementTree import Element, SubElement, tostring
|
|
17
|
+
|
|
18
|
+
from ..database.models import AnalysisResult, CallTreeNode
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class XmiGenerator:
|
|
22
|
+
"""
|
|
23
|
+
Generates XMI 2.5 format UML sequence diagrams from call trees.
|
|
24
|
+
|
|
25
|
+
This class converts call tree structures into XMI XML documents,
|
|
26
|
+
following the UML 2.5 XMI specification for sequence diagrams.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
# XMI/UML namespaces
|
|
30
|
+
XMI_NAMESPACE = "http://www.omg.org/spec/XMI/20131001"
|
|
31
|
+
XMI_URI = "http://www.omg.org/spec/XMI/20131001"
|
|
32
|
+
UML_NAMESPACE = "http://www.eclipse.org/uml2/5.0.0/UML"
|
|
33
|
+
UML_URI = "http://www.eclipse.org/uml2/5.0.0/UML"
|
|
34
|
+
|
|
35
|
+
def __init__(
|
|
36
|
+
self,
|
|
37
|
+
use_module_names: bool = False,
|
|
38
|
+
):
|
|
39
|
+
"""
|
|
40
|
+
Initialize the XMI generator.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
use_module_names: Use SW module names as participants instead of function names
|
|
44
|
+
"""
|
|
45
|
+
self.use_module_names = use_module_names
|
|
46
|
+
self.element_id_counter = 0
|
|
47
|
+
self.participant_map: Dict[str, str] = {} # Map names to XMI IDs
|
|
48
|
+
|
|
49
|
+
def generate(
|
|
50
|
+
self,
|
|
51
|
+
result: AnalysisResult,
|
|
52
|
+
output_path: str,
|
|
53
|
+
) -> None:
|
|
54
|
+
"""
|
|
55
|
+
Generate XMI document and save to file.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
result: Analysis result containing call tree
|
|
59
|
+
output_path: Path to output XMI file
|
|
60
|
+
"""
|
|
61
|
+
if not result.call_tree:
|
|
62
|
+
raise ValueError("Cannot generate XMI: call tree is None")
|
|
63
|
+
|
|
64
|
+
# Build XMI document
|
|
65
|
+
root_element = self._generate_xmi_document(result, result.call_tree)
|
|
66
|
+
|
|
67
|
+
# Pretty print and write to file
|
|
68
|
+
xml_str = self._prettify_xml(root_element)
|
|
69
|
+
output_file = Path(output_path)
|
|
70
|
+
output_file.parent.mkdir(parents=True, exist_ok=True)
|
|
71
|
+
output_file.write_text(xml_str, encoding="utf-8")
|
|
72
|
+
|
|
73
|
+
def _generate_xmi_document(self, result: AnalysisResult, call_tree: CallTreeNode) -> Element:
|
|
74
|
+
"""
|
|
75
|
+
Generate XMI root element with complete document structure.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
result: Analysis result containing metadata
|
|
79
|
+
call_tree: Root node of the call tree (non-optional)
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Root XML Element for the XMI document
|
|
83
|
+
"""
|
|
84
|
+
# Create root element with XMI namespace
|
|
85
|
+
root = Element(
|
|
86
|
+
f"{{{self.XMI_NAMESPACE}}}XMI",
|
|
87
|
+
attrib={
|
|
88
|
+
f"{{{self.XMI_NAMESPACE}}}version": "4.0",
|
|
89
|
+
"xmlns:xmi": self.XMI_URI,
|
|
90
|
+
"xmlns:uml": self.UML_URI,
|
|
91
|
+
},
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Create UML model
|
|
95
|
+
model = SubElement(root, f"{{{self.UML_NAMESPACE}}}Model", attrib={
|
|
96
|
+
f"{{{self.XMI_NAMESPACE}}}id": self._generate_id(),
|
|
97
|
+
"name": f"CallTree_{result.root_function}",
|
|
98
|
+
"visibility": "public",
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
# Package the model
|
|
102
|
+
packaged_element = SubElement(model, f"{{{self.UML_NAMESPACE}}}packagedElement")
|
|
103
|
+
packaged_element.set(f"{{{self.XMI_NAMESPACE}}}id", self._generate_id())
|
|
104
|
+
packaged_element.set("name", f"Sequence_{result.root_function}")
|
|
105
|
+
packaged_element.set("visibility", "public")
|
|
106
|
+
|
|
107
|
+
# Create interaction (sequence diagram container)
|
|
108
|
+
interaction = self._create_interaction(packaged_element, result)
|
|
109
|
+
|
|
110
|
+
# Collect all participants and create lifelines
|
|
111
|
+
participants = self._collect_participants(call_tree)
|
|
112
|
+
lifeline_elements = self._create_lifelines(interaction, participants)
|
|
113
|
+
|
|
114
|
+
# Create messages (function calls)
|
|
115
|
+
self._create_messages(call_tree, lifeline_elements, interaction)
|
|
116
|
+
|
|
117
|
+
return root
|
|
118
|
+
|
|
119
|
+
def _create_interaction(
|
|
120
|
+
self, parent: Element, result: AnalysisResult
|
|
121
|
+
) -> Element:
|
|
122
|
+
"""
|
|
123
|
+
Create UML interaction element (sequence diagram container).
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
parent: Parent element
|
|
127
|
+
result: Analysis result
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
Interaction element
|
|
131
|
+
"""
|
|
132
|
+
interaction = SubElement(parent, f"{{{self.UML_NAMESPACE}}}packagedElement")
|
|
133
|
+
interaction.set(f"{{{self.XMI_NAMESPACE}}}id", self._generate_id())
|
|
134
|
+
interaction.set("name", f"CallSequence_{result.root_function}")
|
|
135
|
+
interaction.set("visibility", "public")
|
|
136
|
+
interaction.set("isReentrant", "false")
|
|
137
|
+
|
|
138
|
+
# Set type to Interaction
|
|
139
|
+
interaction_type = SubElement(interaction, f"{{{self.UML_NAMESPACE}}}ownedAttribute")
|
|
140
|
+
interaction_type.set(f"{{{self.XMI_NAMESPACE}}}id", self._generate_id())
|
|
141
|
+
interaction_type.set("name", "interactionType")
|
|
142
|
+
interaction_type.set("visibility", "public")
|
|
143
|
+
interaction_type.set("type", "Interaction")
|
|
144
|
+
|
|
145
|
+
return interaction
|
|
146
|
+
|
|
147
|
+
def _collect_participants(self, root: CallTreeNode) -> List[str]:
|
|
148
|
+
"""
|
|
149
|
+
Collect all unique participants (functions or modules) in tree.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
root: Root node of call tree
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
List of participant names in the order they are first encountered
|
|
156
|
+
"""
|
|
157
|
+
participants = []
|
|
158
|
+
|
|
159
|
+
def traverse(node: CallTreeNode):
|
|
160
|
+
# Use module name if enabled, otherwise use function name
|
|
161
|
+
if self.use_module_names:
|
|
162
|
+
participant = (
|
|
163
|
+
node.function_info.sw_module
|
|
164
|
+
or Path(node.function_info.file_path).stem
|
|
165
|
+
)
|
|
166
|
+
else:
|
|
167
|
+
participant = node.function_info.name
|
|
168
|
+
|
|
169
|
+
# Add participant only if not already in the list
|
|
170
|
+
if participant not in participants:
|
|
171
|
+
participants.append(participant)
|
|
172
|
+
|
|
173
|
+
for child in node.children:
|
|
174
|
+
traverse(child)
|
|
175
|
+
|
|
176
|
+
traverse(root)
|
|
177
|
+
return participants
|
|
178
|
+
|
|
179
|
+
def _create_lifelines(
|
|
180
|
+
self, interaction: Element, participants: List[str]
|
|
181
|
+
) -> Dict[str, Element]:
|
|
182
|
+
"""
|
|
183
|
+
Create UML lifelines for each participant.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
interaction: Interaction element
|
|
187
|
+
participants: List of participant names
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
Dictionary mapping participant names to their lifeline elements
|
|
191
|
+
"""
|
|
192
|
+
lifeline_elements = {}
|
|
193
|
+
|
|
194
|
+
for idx, participant in enumerate(participants):
|
|
195
|
+
# Create lifeline
|
|
196
|
+
lifeline = SubElement(interaction, f"{{{self.UML_NAMESPACE}}}lifeline")
|
|
197
|
+
lifeline_id = self._generate_id()
|
|
198
|
+
lifeline.set(f"{{{self.XMI_NAMESPACE}}}id", lifeline_id)
|
|
199
|
+
lifeline.set("name", participant)
|
|
200
|
+
lifeline.set("visibility", "public")
|
|
201
|
+
|
|
202
|
+
# Create represents property (connects to classifier)
|
|
203
|
+
represents = SubElement(lifeline, f"{{{self.UML_NAMESPACE}}}represents")
|
|
204
|
+
represents_id = self._generate_id()
|
|
205
|
+
represents.set(f"{{{self.XMI_NAMESPACE}}}id", represents_id)
|
|
206
|
+
represents.set("name", participant)
|
|
207
|
+
|
|
208
|
+
# Store mapping
|
|
209
|
+
self.participant_map[participant] = lifeline_id
|
|
210
|
+
lifeline_elements[participant] = lifeline
|
|
211
|
+
|
|
212
|
+
return lifeline_elements
|
|
213
|
+
|
|
214
|
+
def _create_messages(
|
|
215
|
+
self,
|
|
216
|
+
root: CallTreeNode,
|
|
217
|
+
lifeline_elements: Dict[str, Element],
|
|
218
|
+
interaction: Element,
|
|
219
|
+
) -> None:
|
|
220
|
+
"""
|
|
221
|
+
Create UML messages (function calls) between lifelines.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
root: Root node of call tree
|
|
225
|
+
lifeline_elements: Dictionary of lifeline elements
|
|
226
|
+
interaction: Interaction element
|
|
227
|
+
"""
|
|
228
|
+
message_counter = 0
|
|
229
|
+
|
|
230
|
+
def traverse(node: CallTreeNode, parent_participant: Optional[str] = None):
|
|
231
|
+
nonlocal message_counter
|
|
232
|
+
|
|
233
|
+
# Determine current participant
|
|
234
|
+
if self.use_module_names:
|
|
235
|
+
current_participant = (
|
|
236
|
+
node.function_info.sw_module
|
|
237
|
+
or Path(node.function_info.file_path).stem
|
|
238
|
+
)
|
|
239
|
+
else:
|
|
240
|
+
current_participant = node.function_info.name
|
|
241
|
+
|
|
242
|
+
# Create message from parent to current
|
|
243
|
+
if parent_participant:
|
|
244
|
+
message = SubElement(interaction, f"{{{self.UML_NAMESPACE}}}message")
|
|
245
|
+
message_id = self._generate_id()
|
|
246
|
+
message.set(f"{{{self.XMI_NAMESPACE}}}id", message_id)
|
|
247
|
+
message.set("name", node.function_info.name)
|
|
248
|
+
message.set("visibility", "public")
|
|
249
|
+
message.set("messageSort", "synchCall")
|
|
250
|
+
|
|
251
|
+
# Set message signature
|
|
252
|
+
signature = self._format_message_signature(node)
|
|
253
|
+
message.set("signature", signature)
|
|
254
|
+
|
|
255
|
+
# Connect to lifelines
|
|
256
|
+
send_event = SubElement(message, f"{{{self.UML_NAMESPACE}}}sendEvent")
|
|
257
|
+
send_event.set(f"{{{self.XMI_NAMESPACE}}}id", self._generate_id())
|
|
258
|
+
|
|
259
|
+
receive_event = SubElement(message, f"{{{self.UML_NAMESPACE}}}receiveEvent")
|
|
260
|
+
receive_event.set(f"{{{self.XMI_NAMESPACE}}}id", self._generate_id())
|
|
261
|
+
|
|
262
|
+
# Set source and target
|
|
263
|
+
message.set(
|
|
264
|
+
"sendEvent",
|
|
265
|
+
f"{{{self.XMI_NAMESPACE}}}{self.participant_map.get(parent_participant, '')}"
|
|
266
|
+
)
|
|
267
|
+
message.set(
|
|
268
|
+
"receiveEvent",
|
|
269
|
+
f"{{{self.XMI_NAMESPACE}}}{self.participant_map.get(current_participant, '')}"
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
message_counter += 1
|
|
273
|
+
|
|
274
|
+
# Mark recursive calls
|
|
275
|
+
if node.is_recursive:
|
|
276
|
+
message.set("messageSort", "reply")
|
|
277
|
+
|
|
278
|
+
# Traverse children
|
|
279
|
+
for child in node.children:
|
|
280
|
+
traverse(child, current_participant)
|
|
281
|
+
|
|
282
|
+
# Start traversal from root's children
|
|
283
|
+
for child in root.children:
|
|
284
|
+
traverse(child, None)
|
|
285
|
+
|
|
286
|
+
def _format_message_signature(self, node: CallTreeNode) -> str:
|
|
287
|
+
"""
|
|
288
|
+
Format message signature with parameters.
|
|
289
|
+
|
|
290
|
+
Args:
|
|
291
|
+
node: Call tree node
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
Formatted signature string
|
|
295
|
+
"""
|
|
296
|
+
func = node.function_info
|
|
297
|
+
|
|
298
|
+
if not func.parameters:
|
|
299
|
+
return f"{func.name}()"
|
|
300
|
+
|
|
301
|
+
params = []
|
|
302
|
+
for param in func.parameters:
|
|
303
|
+
if param.name:
|
|
304
|
+
params.append(param.name)
|
|
305
|
+
else:
|
|
306
|
+
type_str = param.param_type
|
|
307
|
+
if param.is_pointer:
|
|
308
|
+
type_str += "*"
|
|
309
|
+
params.append(type_str)
|
|
310
|
+
|
|
311
|
+
return f"{func.name}({', '.join(params)})"
|
|
312
|
+
|
|
313
|
+
def _generate_id(self) -> str:
|
|
314
|
+
"""
|
|
315
|
+
Generate unique XMI ID.
|
|
316
|
+
|
|
317
|
+
Returns:
|
|
318
|
+
Unique identifier string
|
|
319
|
+
"""
|
|
320
|
+
self.element_id_counter += 1
|
|
321
|
+
return f"calltree_{self.element_id_counter}"
|
|
322
|
+
|
|
323
|
+
def _prettify_xml(self, element: Element) -> str:
|
|
324
|
+
"""
|
|
325
|
+
Convert XML element to pretty-printed string.
|
|
326
|
+
|
|
327
|
+
Args:
|
|
328
|
+
element: Root XML element
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
Pretty-printed XML string
|
|
332
|
+
"""
|
|
333
|
+
rough_string = tostring(element, encoding="unicode")
|
|
334
|
+
reparsed = minidom.parseString(rough_string)
|
|
335
|
+
pretty_xml = reparsed.toprettyxml(indent=" ")
|
|
336
|
+
|
|
337
|
+
# Add XML declaration and comments
|
|
338
|
+
lines = pretty_xml.split('\n')
|
|
339
|
+
filtered_lines = [line for line in lines if line.strip()]
|
|
340
|
+
|
|
341
|
+
return '\n'.join(filtered_lines)
|
|
342
|
+
|
|
343
|
+
def generate_to_string(self, result: AnalysisResult) -> str:
|
|
344
|
+
"""
|
|
345
|
+
Generate XMI document as string without writing to file.
|
|
346
|
+
|
|
347
|
+
Args:
|
|
348
|
+
result: Analysis result
|
|
349
|
+
|
|
350
|
+
Returns:
|
|
351
|
+
XMI document as string
|
|
352
|
+
"""
|
|
353
|
+
if not result.call_tree:
|
|
354
|
+
raise ValueError("Cannot generate XMI: call tree is None")
|
|
355
|
+
|
|
356
|
+
root_element = self._generate_xmi_document(result, result.call_tree)
|
|
357
|
+
return self._prettify_xml(root_element)
|
|
@@ -58,6 +58,29 @@ class CParser:
|
|
|
58
58
|
"_Generic",
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
# AUTOSAR and standard C macros to exclude from function detection
|
|
62
|
+
# These macros look like function calls but should not be parsed as functions
|
|
63
|
+
AUTOSAR_MACROS = {
|
|
64
|
+
# Standard C integer literal macros (stdint.h)
|
|
65
|
+
"INT8_C",
|
|
66
|
+
"INT16_C",
|
|
67
|
+
"INT32_C",
|
|
68
|
+
"INT64_C",
|
|
69
|
+
"UINT8_C",
|
|
70
|
+
"UINT16_C",
|
|
71
|
+
"UINT32_C",
|
|
72
|
+
"UINT64_C",
|
|
73
|
+
"INTMAX_C",
|
|
74
|
+
"UINTMAX_C",
|
|
75
|
+
# AUTOSAR tool-specific macros
|
|
76
|
+
"TS_MAKEREF2CFG",
|
|
77
|
+
"TS_MAKENULLREF2CFG",
|
|
78
|
+
"TS_MAKEREFLIST2CFG",
|
|
79
|
+
# Common AUTOSAR configuration macros
|
|
80
|
+
"STD_ON",
|
|
81
|
+
"STD_OFF",
|
|
82
|
+
}
|
|
83
|
+
|
|
61
84
|
# Common AUTOSAR types
|
|
62
85
|
AUTOSAR_TYPES = {
|
|
63
86
|
"uint8",
|
|
@@ -244,6 +267,16 @@ class CParser:
|
|
|
244
267
|
if return_type in self.C_KEYWORDS or function_name in self.C_KEYWORDS:
|
|
245
268
|
return None
|
|
246
269
|
|
|
270
|
+
# Skip AUTOSAR and standard C macros that look like function calls
|
|
271
|
+
# This prevents false positives on macros like UINT32_C(value), TS_MAKEREF2CFG(...)
|
|
272
|
+
if function_name in self.AUTOSAR_MACROS:
|
|
273
|
+
return None
|
|
274
|
+
|
|
275
|
+
# Skip standard C integer literal macros (those ending with _C)
|
|
276
|
+
# These are defined in stdint.h and look like: INT32_C(42), UINT64_C(100)
|
|
277
|
+
if function_name.endswith("_C"):
|
|
278
|
+
return None
|
|
279
|
+
|
|
247
280
|
# Skip common control structures
|
|
248
281
|
if function_name in ["if", "for", "while", "switch", "case", "else"]:
|
|
249
282
|
return None
|
autosar_calltree/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: autosar-calltree
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A Python tool to analyze C/AUTOSAR codebases and generate function call trees with Mermaid and XMI output
|
|
5
5
|
Author-email: melodypapa <melodypapa@outlook.com>
|
|
6
6
|
Maintainer-email: melodypapa <melodypapa@outlook.com>
|
|
@@ -255,7 +255,7 @@ default_module: "Other"
|
|
|
255
255
|
|
|
256
256
|
**Usage**:
|
|
257
257
|
```bash
|
|
258
|
-
calltree --start-function Demo_Init --module-config module_mapping.yaml --use-module-names --max-depth 3
|
|
258
|
+
calltree --start-function Demo_Init --module-config demo/module_mapping.yaml --use-module-names --max-depth 3 --output demo/demo_sequence.md
|
|
259
259
|
```
|
|
260
260
|
|
|
261
261
|
This generates diagrams with:
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
autosar_calltree/__init__.py,sha256=WiP2aFfs0H3ze4X8tQg6ZiStdzgrp6uC8DPRUyGm_zg,660
|
|
2
|
-
autosar_calltree/version.py,sha256=
|
|
2
|
+
autosar_calltree/version.py,sha256=Nt6KvWNqsurDjWOhy4Xi-L1EtfOXOROb5rxxO8OE_bA,142
|
|
3
3
|
autosar_calltree/analyzers/__init__.py,sha256=qUvB7CAa5xNcUYkhD7Rha-9quPG8yQJqg-GikHD41U0,119
|
|
4
4
|
autosar_calltree/analyzers/call_tree_builder.py,sha256=tSsIj_BHzT4XQ-XsXXfyU-KyGK61p6O7nLBx1AiwxCA,11627
|
|
5
5
|
autosar_calltree/cli/__init__.py,sha256=qwsSUuDyV6i1PYS7Mf6JBkBJKtcldxiIh5S0wOucWVY,76
|
|
6
|
-
autosar_calltree/cli/main.py,sha256=
|
|
6
|
+
autosar_calltree/cli/main.py,sha256=f9awQW_1dKIc1IjhOp5_yx7f2CzRybNFKQt2tILwj1c,12676
|
|
7
7
|
autosar_calltree/config/__init__.py,sha256=mSrB2uvrax_MTgGynfPObXYUh6eCe5BZD21_cebfMQM,258
|
|
8
8
|
autosar_calltree/config/module_config.py,sha256=--ptsY6drvVKn_HD5_JDEpCv9D1xI8kiJXi8bwrSFBI,6329
|
|
9
9
|
autosar_calltree/database/__init__.py,sha256=qg0IfUGgkecJQXqe9lPrU0Xbu-hBZa8NOe8E8UZqC_s,405
|
|
10
10
|
autosar_calltree/database/function_database.py,sha256=PJghwv2Duxx7vSIvApyVwg4N_bCTfnk85mtA89BpIuA,17561
|
|
11
11
|
autosar_calltree/database/models.py,sha256=xo85zao2LDHJMR6FeMVxopPyXxEv7jQUzeh4fzHwNKo,6265
|
|
12
|
-
autosar_calltree/generators/__init__.py,sha256=
|
|
12
|
+
autosar_calltree/generators/__init__.py,sha256=5gl3dF3imJIsvfmdg0bkZdnQ9vFWCTlpMWEhz6I_IZg,178
|
|
13
13
|
autosar_calltree/generators/mermaid_generator.py,sha256=LcmWOACLAw3r7UQlnSlTM-_kpKQ6RGdgc6aNqXeMF7A,16191
|
|
14
|
+
autosar_calltree/generators/xmi_generator.py,sha256=ndvDapHppOoDQ9q5Zu9b1AFbUKKc8q3copUti3UaFZM,12168
|
|
14
15
|
autosar_calltree/parsers/__init__.py,sha256=O0NTHrZqe6GXvU9_bLuAoAV_hxv7gHOgkH8KWSBmX1Y,151
|
|
15
16
|
autosar_calltree/parsers/autosar_parser.py,sha256=iwF1VR4NceEfmc3gPP31CcVNPfRRVTj_aA6N94saXDA,10750
|
|
16
|
-
autosar_calltree/parsers/c_parser.py,sha256=
|
|
17
|
-
autosar_calltree-0.
|
|
18
|
-
autosar_calltree-0.
|
|
19
|
-
autosar_calltree-0.
|
|
20
|
-
autosar_calltree-0.
|
|
21
|
-
autosar_calltree-0.
|
|
22
|
-
autosar_calltree-0.
|
|
17
|
+
autosar_calltree/parsers/c_parser.py,sha256=2LCDVZ8bcrBiQe9DK7kNMmvzhGegEDfd57KbI5JB43A,15846
|
|
18
|
+
autosar_calltree-0.4.0.dist-info/licenses/LICENSE,sha256=Xy30Wm38nOLXLZZFgn9oD_3UcayYkm81xtn8IByrBlk,1067
|
|
19
|
+
autosar_calltree-0.4.0.dist-info/METADATA,sha256=9O3LbtSX1byivDrDmCATcTSX5fT_Cxb-E6F0pyqhyIE,15566
|
|
20
|
+
autosar_calltree-0.4.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
21
|
+
autosar_calltree-0.4.0.dist-info/entry_points.txt,sha256=HfntIC1V_COOhGJ-OhtLKH_2vJ1jQy5Hlz8NmcJg4TQ,54
|
|
22
|
+
autosar_calltree-0.4.0.dist-info/top_level.txt,sha256=eusKGYzQfbhwIFDsUYTby40SdMpe95Y9GtR0l1GVIDQ,17
|
|
23
|
+
autosar_calltree-0.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|