From 65e399fa7057a3fe2e4ff3ed32052f88aa8bfd84 Mon Sep 17 00:00:00 2001 From: Ferrari Martino Giordano Date: Fri, 8 Mar 2024 17:18:38 +0100 Subject: [PATCH] feat: working version --- .gitignore | 1 + autodoc/__init__.py | 1 + autodoc/__main__.py | 104 ++-- autodoc/__pycache__/__main__.cpython-311.pyc | Bin 4334 -> 4293 bytes autodoc/__pycache__/autodoc.cpython-311.pyc | Bin 8253 -> 18803 bytes autodoc/autodoc.py | 498 ++++++++++++++----- 6 files changed, 439 insertions(+), 165 deletions(-) diff --git a/.gitignore b/.gitignore index ea1472e..77d26fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ output/ +__pycache__ diff --git a/autodoc/__init__.py b/autodoc/__init__.py index e69de29..18299c9 100644 --- a/autodoc/__init__.py +++ b/autodoc/__init__.py @@ -0,0 +1 @@ +from autodoc.autodoc import * diff --git a/autodoc/__main__.py b/autodoc/__main__.py index 79fa729..24bbe14 100644 --- a/autodoc/__main__.py +++ b/autodoc/__main__.py @@ -4,62 +4,76 @@ Main entry point for the MARTe Autodoc project" Author: Martino Ferrari Email: martinogiordano.ferrari@iter.org """ -from argparse import ArgumentParser +import json import logging -import sys import os import pprint +import sys +from argparse import ArgumentParser -from MARTe.StandardParser import StandardParser -from MARTe.StandardParser import ParseException -import json +from MARTe.StandardParser import ParseException, StandardParser import autodoc __version__ = "0.0.0" + def __args__(): - """Parse arguments.""" - parser = ArgumentParser( - prog="autodoc", - description="MARTe configuration auto documentation tool", - ) - parser.add_argument("filename", help="Configuration file to document", type=str) - parser.add_argument("--type", choices=["json", "marte"], default="marte", help="Configuration file type (default: `marte`)") - parser.add_argument("--loglevel", choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], default="ERROR", help="Logging level (default: `ERROR`)") - parser.add_argument("--version", action="version", version=__version__) - return parser.parse_args() + """Parse arguments.""" + parser = ArgumentParser( + prog="autodoc", + description="MARTe configuration auto documentation tool", + ) + parser.add_argument("filename", help="Configuration file to document", type=str) + parser.add_argument( + "--type", + choices=["json", "marte"], + default="marte", + help="Configuration file type (default: `marte`)", + ) + parser.add_argument( + "--loglevel", + choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], + default="ERROR", + help="Logging level (default: `ERROR`)", + ) + parser.add_argument("--version", action="version", version=__version__) + parser.add_argument( + "-d", "--destination", help="Destination folder", type=str, default="." + ) + return parser.parse_args() + def main(): - """Main function.""" - args = __args__() - logging.basicConfig(level=args.loglevel) - logging.info(f"AutoDoc v{__version__}") - if not os.path.exists(args.filename): - logging.error(f"Specified file `{args.filename}` does not exists") - sys.exit(1) - config = {} - if args.type == 'marte': - parser = StandardParser() - try: - config = parser.parse_file(args.filename) - except ParseException as e: - logging.error(f"Impossible to parse file `{args.filename}` at position ({e.line},{e.col}): {e.msg}`") - sys.exit(1) - except Exception as e: - logging.error(f"Sometihng went wrong with file `{args.filename}`") - sys.exit(1) - else: - with open(args.filename, "r") as file: - config = json.load(file) - if not config: - logging.error(f"Impossible to load configuration `{args.filename}`") - sys.exit(1) - print(f"# `{os.path.splitext(os.path.basename(args.filename))[0]}` Documentation") - for label, obj in config.items(): - if 'Class' in obj: - autodoc.document(label, obj) + """Main function.""" + args = __args__() + logging.basicConfig(level=args.loglevel) + logging.info(f"AutoDoc v{__version__}") + if not os.path.exists(args.filename): + logging.error(f"Specified file `{args.filename}` does not exists") + sys.exit(1) + config = {} + if args.type == "marte": + parser = StandardParser() + try: + config = parser.parse_file(args.filename) + except ParseException as e: + logging.error( + f"Impossible to parse file `{args.filename}` at position ({e.line},{e.col}): {e.msg}`" + ) + sys.exit(1) + except Exception as e: + logging.error(f"Sometihng went wrong with file `{args.filename}`") + sys.exit(1) + else: + with open(args.filename, "r") as file: + config = json.load(file) + if not config: + logging.error(f"Impossible to load configuration `{args.filename}`") + sys.exit(1) + filename = os.path.splitext(os.path.basename(args.filename))[0] + autodoc.document(filename, args, config) -if __name__ == '__main__': - main() +if __name__ == "__main__": + main() diff --git a/autodoc/__pycache__/__main__.cpython-311.pyc b/autodoc/__pycache__/__main__.cpython-311.pyc index d7eacc9da811eb4e2a25c682b69ac7ca79c2daaa..34b8f58d4d0684ae31e174e9df0235e0d42c4651 100644 GIT binary patch delta 1823 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 C1}Coo diff --git a/autodoc/__pycache__/autodoc.cpython-311.pyc b/autodoc/__pycache__/autodoc.cpython-311.pyc index bb6e121fde6dbad39738422441fe0bc9eff42277..a12babdc8a9048672e422adf577af4b77e6424a9 100644 GIT binary patch literal 18803 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 i%)z6sLNGzu7AyAv literal 8253 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 {l} ({sig["Type"]})' - if "OutputSignals" in obj: - for i, (l, sig) in enumerate(obj["OutputSignals"].items()): - if sig['DataSource'] not in datasources: - datasources[sig['DataSource']] = {} - if l not in datasources[sig['DataSource']]: - datasources[sig['DataSource']][l] = [f'fn{fn}:out{i}'] - else: - datasources[sig['DataSource']][l].append(f'fn{fn}:out{i}') - if i != 0: - outputs += ' | ' - outputs += f' {l} ({sig["Type"]})' - node += '{ { '+inputs+' } | { '+ outputs +' } }"];' - else: - node += '"];' - if "InputSignals" in obj: - for i, (l, sig) in enumerate(obj["InputSignals"].items()): - if sig['DataSource'] not in datasources: - datasources[sig['DataSource']] = [] - if (fn, 'in') not in datasources[sig['DataSource']]: - datasources[sig['DataSource']].append((fn, 'in')) - if "OutputSignals" in obj: - for i, (l, sig) in enumerate(obj["OutputSignals"].items()): - if sig['DataSource'] not in datasources: - datasources[sig['DataSource']] = [] - if (fn, 'out') not in datasources[sig['DataSource']]: - datasources[sig['DataSource']].append((fn, 'out')) - print(node) - for l, obj in datasources.items(): - logging.debug(f"datasource: {l}") - ds = app['+Data'][f'+{l}'] - arrows = '' - node = f' ds{l} [label="{l}\n{ds["Class"]}' - if full: - node += ' | ' - for i, s in enumerate(obj): - if i > 0: + +def __sig_name__(name): + return name.replace(".", "_") + + +def __type_bytes__(mtype): + if mtype.startswith("uint"): + return int(mtype[4:]) // 8 + if mtype.startswith("int"): + return int(mtype[3:]) // 8 + if mtype.startswith("float"): + return int(mtype[5:]) // 8 + if mtype == "bool": + return 1 + logging.debug(f"Type `{mtype}` unknow, size 1 byte") + return 1 + + +def __type_size__(mtype): + return __type_bytes__(mtype[0]) * mtype[1] + + +def __num_bytes__(sig): + noe = 1 if "NumberOfElements" not in sig else int(sig["NumberOfElements"]) + nod = 1 if "NumberOfDimensions" not in sig else int(sig["NumberOfDimensions"]) + bytes = __type_bytes__(sig["Type"]) + return noe * nod * bytes + + +def __doc_app_state__(state, tab=" │ "): + res = "" + if "+Threads" in state: + for i, tname in enumerate(state["+Threads"]): + if tname[0] == "+": + ch = "├─●" if i < len(state["+Threads"]) - 1 else "╰─●" + res += f"{tab} {ch} {tname[1:]}\n" + return res + + +def __doc_obj__(label, obj, id): + node = f' {id} [label="{label}\n{obj["Class"]} | ' + return node + + +def __sig_type__(sig): + type_name = sig["Type"] + noe = sig["NumberOfElements"] if "NumberOfElements" in sig else 1 + nod = sig["NumberOfDimensions"] if "NumberOfDimensions" in sig else 1 + dim = int(noe) * int(nod) + return (type_name, dim) + + +def __sig_alias__(name, signal): + return name if "Alias" not in signal else signal["Alias"] + + +def __doc_common_gam__(name, obj, edges): + inputs = "" + outputs = "" + if "InputSignals" in obj: + for i, (l, sig) in enumerate(obj["InputSignals"].items()): + alias = __sig_alias__(l, sig) + mtype = __sig_type__(sig) + datasrc = sig["DataSource"] + edges.append( + __edge__( + __sig__(datasrc, alias, mtype), + __sig__(name, l, mtype), + ) + ) + if i != 0: + inputs += " | " + inputs += f" {l}" + if "OutputSignals" in obj: + for i, (l, sig) in enumerate(obj["OutputSignals"].items()): + alias = __sig_alias__(l, sig) + mtype = __sig_type__(sig) + datasrc = sig["DataSource"] + edges.append( + __edge__( + __sig__(name, l, mtype), + __sig__(datasrc, alias, mtype), + ) + ) + if i != 0: + outputs += " | " + outputs += f" {l}" + return "{ {" + inputs + " } | { " + outputs + "} }", edges + + +def __doc_triggered_iogam__(name, obj, edges): + node = "" + if "InputSignals" in obj: + for i, (l, sig) in enumerate(obj["InputSignals"].items()): + alias = __sig_alias__(l, sig) + mtype = __sig_type__(sig) + datasrc = sig["DataSource"] + edges.append( + __edge__( + __sig__(datasrc, alias, mtype), + __sig__(name, l, mtype), + ) + ) + if i > 1: node += " | " - node += f' {s}' - for c in obj[s]: - if c.split(':')[1].startswith('in'): - arrows += f' ds{l}:sig{i} -> {c};\n' - else: - arrows += f' {c} -> ds{l}:sig{i};\n' - else: - for (fn, dir) in obj: - if dir == 'in': - arrows += f' ds{l} -> fn{fn};\n' - else: - arrows += f' fn{fn} -> ds{l};\n' - node += '" color=blue];' - print(node) - print(arrows) - print('}\n```') + node += f" " + + if i == 0: + node += "Trigger | { { " + else: + node += f"{l}" + node += " } | { " + if "OutputSignals" in obj: + for i, (l, sig) in enumerate(obj["OutputSignals"].items()): + alias = __sig_alias__(l, sig) + mtype = __sig_type__(sig) + datasrc = sig["DataSource"] + edges.append( + __edge__( + __sig__(name, l, mtype), + __sig__(datasrc, alias, mtype), + ) + ) + if i != 0: + node += " | " + node += f" {l} " + node += " } }" + return node, edges + + +def __doc_iogam__(id, obj, edges): + node = "" + if "InputSignals" in obj and "OutputSignals" in obj: + inputs, outputs = obj["InputSignals"], obj["OutputSignals"] + output_names = list(outputs.keys()) + input_names = list(inputs.keys()) + j = 0 + isize = 0 + osize = 0 + i = 0 + irow = "" + orow = "" + + while i < len(inputs): + in_label = input_names[i] + input = inputs[in_label] + if irow: + irow += " | " + irow += f" {in_label}" + isize += __num_bytes__(input) + i += 1 + alias = __sig_alias__(in_label, input) + mtype = __sig_type__(input) + datasrc = input["DataSource"] + edges.append( + __edge__( + __sig__(datasrc, alias, mtype), + __sig__(id, in_label, mtype), + ) + ) + while osize < isize and j < len(outputs): + out_label = output_names[j] + output = outputs[out_label] + osize += __num_bytes__(output) + if orow: + orow += " | " + orow += f" {out_label}" + j += 1 + + alias = __sig_alias__(out_label, output) + mtype = __sig_type__(output) + datasrc = output["DataSource"] + edges.append( + __edge__( + __sig__(id, out_label, mtype), + __sig__(datasrc, alias, mtype), + ) + ) + if isize == osize and irow and orow: + if node: + node += " | " + node += "{ {" + irow + "} | {" + orow + "} }" + irow = "" + orow = "" + if irow or orow: + if node: + node += " | " + node += "{ {" + irow + "} | {" + orow + "} }" + return node, edges + + +def __doc_constgam__(id, obj, edges): + node = "" + if "OutputSignals" in obj: + for i, (l, sig) in enumerate(obj["OutputSignals"].items()): + datasrc = sig["DataSource"] + alias = __sig_alias__(l, sig) + mtype = __sig_type__(sig) + edges.append( + __edge__(__sig__(id, l, mtype), __sig__(datasrc, alias, mtype)) + ) + if i != 0: + node += " | " + node += f' {sig["Default"]} ' + + node += "" + return node, edges + + +def __doc_gam__(label, obj, edges): + id = f"fn{label}" + cls = obj["Class"] + node = f' {id} [label="{label}\n{obj["Class"]} | ' + if cls == "ConstantGAM": + sigs, datasources = __doc_constgam__(id, obj, edges) + elif cls == "IOGAM": + sigs, datasources = __doc_iogam__(id, obj, edges) + elif cls == "TriggeredIOGAM": + sigs, datasources = __doc_triggered_iogam__(id, obj, edges) + else: + sigs, datasources = __doc_common_gam__(id, obj, edges) + if sigs: + node += sigs + '"];' + else: + node = "" + return node, datasources + + +def __process_gamds__(name, signals): + node = "" + for i, sig_name in enumerate(signals): + sig_type = signals[sig_name] + node += f'{name}_{__sig_name__(sig_name)}[ label=" {name}::{sig_name} ({sig_type[0]}[{sig_type[1]}])", color=blue];\n' + return node + + +def __process_ds__(name, obj, edges): + cls = obj["Class"] + sigs = {} + node = "" + for edge in edges: + if edge[0][0] == name: + sigs[edge[0][1]] = edge[0][2] + if edge[1][0] == name: + sigs[edge[1][1]] = edge[1][2] + if sigs: + if cls == "GAMDataSource": + node = __process_gamds__(name, sigs) + else: + order = [] + if "Signals" in obj: + for sig in obj["Signals"]: + if sig in sigs: + order.append(sig) + else: + order = list(sigs.keys()) + + node = f'{name} [label="{name}\n{cls} | ' + for i, sig_name in enumerate(order): + sig_type = sigs[sig_name] + if i > 0: + node += " | " + node += f"<{__sig_name__(sig_name)}> {sig_name} ({sig_type[0]}[{sig_type[1]}])" + node += '", color=blue];\n' + return node + + +def __process_edges__(edges, datasources): + arrows = "" + for source, target in edges: + src_obj = source[0] + src_sig = __sig_name__(source[1]) + trg_obj = target[0] + trg_sig = __sig_name__(target[1]) + a = f"{src_obj}" + b = f"{trg_obj}" + if src_obj in datasources: + if datasources[src_obj] == "GAMDataSource": + a += f"_{src_sig}" + else: + a += f":{src_sig}" + else: + a += f":out_{src_sig}" + if trg_obj in datasources: + if datasources[trg_obj] == "GAMDataSource": + b += f"_{trg_sig}" + else: + b += f":{trg_sig}" + else: + b += f":in_{trg_sig}" + arrows += f"{a} -> {b};\n" + return arrows + + +def __doc_state__(label, state, app): + mdstate = "" + graph = f"digraph {label[1:]}" + "{\n" + graph += "grapn [ranksep=4];\n" + graph += "rankdir = LR;\n" + graph += "beautify = true;\n" + graph += "node [shape=record];\n" + graph += "\n" + arrows = "" + ext = "" + edges = [] + datasources = {} + if "+Threads" in state: + for tname, obj in state["+Threads"].items(): + if tname[0] == "+": + # graph += f"subgraph cluster_{tname[1:]}" + "{\n" + if "Functions" in obj: + fns = obj["Functions"] + for fn in fns: + obj = app["+Functions"][f"+{fn}"] + node, edges = __doc_gam__(fn, obj, edges) + graph += f"{node}\n" + # graph += f' label = "{tname[1:]}";\n' + # graph += "}\n" + if "+Data" in app: + for key, obj in app["+Data"].items(): + if key[0] == "+": + datasources[key[1:]] = obj["Class"] + node = __process_ds__(key[1:], obj, edges) + graph += node + arrows = __process_edges__(edges, datasources) + graph += "\n" + ext + "\n" + arrows + graph += "}\n" + fname = f"{label[1:]}" + + with open(os.path.join(__PATH__, f"{fname}.dot"), "w") as file: + file.write(graph) + os.system( + f"dot -Tsvg -o{os.path.join(__PATH__, fname)}.svg {os.path.join(__PATH__, fname)}.dot" + ) + mdstate += f"![{fname}]({fname}.svg)\n" + return mdstate + def __doc_application__(label, app): - print() - print(f"## Real-time application: `{label[1:]}`") - print() - print(f"Below are descrbed the states and threads of the real-time application {label[1:]}.") - print("```") - print(f'╭{"─"*(len(label)-1)}╮') - print(f'│{label[1:]}│') - print(f'╰┬{"─"*(len(label)-2)}╯') - states = app['+States'] - for i, (label, obj) in enumerate(states.items()): - ch = '├─▷' if i < len(states) - 1 else '╰─▷' - tab = ' │ ' if i < len(states) - 1 else ' ' - if label[0] == '+': - print(f' {ch} {label[1:]}') - __doc_app_state__(obj, tab) - print("```") - for label, obj in states.items(): - if label[0] == '+': - print() - print(f'### State `{label[1:]}`') - __doc_state__(label, obj, app) + mdapp = f'\n## Real-time application "{label[1:]}"\n\n' + mdapp += f"Below are descrbed the states and threads of the real-time application {label[1:]}.\n" + mdapp += "```\n" + mdapp += f'╭{"─"*(len(label)-1)}╮\n' + mdapp += f"│{label[1:]}│\n" + mdapp += f'╰┬{"─"*(len(label)-2)}╯\n' + states = app["+States"] + for i, (label, obj) in enumerate(states.items()): + ch = "├─▷" if i < len(states) - 1 else "╰─▷" + tab = " │ " if i < len(states) - 1 else " " + if label[0] == "+": + mdapp += f" {ch} {label[1:]}\n" + mdapp += __doc_app_state__(obj, tab) + mdapp += "```\n" + for label, obj in states.items(): + if label[0] == "+": + mdapp += f'\n### State "{label[1:]}"\n' + mdapp += __doc_state__(label, obj, app) + return mdapp +def document(fname, args, config): + """Document MARTe object.""" + global __PATH__ + __PATH__ = os.path.join(args.destination, fname) + if not os.path.isdir(__PATH__): + os.mkdir(__PATH__) -def document(label, obj): - """Document MARTe object.""" - if obj['Class'] == 'RealTimeApplication': - __doc_application__(label, obj) - if obj['Class'] == 'StateMachine': - print() - print(f"## State-Machine `{label[1:]}`") - + mddoc = f"# {fname}\n" + for label, obj in config.items(): + if "Class" in obj: + if obj["Class"] == "RealTimeApplication": + mddoc += __doc_application__(label, obj) + if obj["Class"] == "StateMachine": + mddoc += f'\n## State-Machine "{label[1:]}"' + with open(os.path.join(__PATH__, f"{fname}.md"), "w") as file: + file.write(mddoc)