def sanity_test(): # pylint: disable=import-outside-toplevel from argparse import ArgumentParser import traceback # pylint: enable=import-outside-toplevel ap = ArgumentParser() ap.add_argument("item", metavar="FILE|DIR") ap.add_argument("--no-tb", action="store_true", default=False, help="Do not show debug-style backtrace") options = ap.parse_args() mh = Message_Handler("debug") mh.sort_messages = False mh.colour = False try: register_item(mh, options.item, options) except Error: if not options.no_tb: traceback.print_exc() except ICE as ice: if not options.no_tb: traceback.print_exc() print("ICE:", ice.reason) for dirname in sorted(tree): print("Showing config for %s" % dirname) node = tree[dirname] print(" Root: %s" % node.project_root) print(" File: %s" % ", ".join(node.config_files)) cfg = node.config if cfg is None: print(" No config attached") continue print(" Enabled = %s" % cfg.enabled) print(" Octave = %s" % cfg.octave) print(" Rules = %u" % len(cfg.style_rules)) print(" SConf = %s" % cfg.style_config) print(" Metrics = %u" % len(cfg.enabled_metrics)) print(" Limits = %s" % cfg.metric_limits)
def main_handler(): clp = command_line.create_basic_clp() # Extra output options clp["output_options"].add_argument( "--html", default=None, help="Write report to given file as HTML") clp["output_options"].add_argument("--json", default=None, help="Produce JSON report") options = command_line.parse_args(clp) if options.html: if options.json: clp["ap"].error("Cannot produce JSON and HTML at the same time") if os.path.exists(options.html) and not os.path.isfile(options.html): clp["ap"].error("Cannot write to %s: it is not a file" % options.html) mh = HTML_Message_Handler("lint", options.html) elif options.json: if os.path.exists(options.json) and not os.path.isfile(options.json): clp["ap"].error("Cannot write to %s: it is not a file" % options.json) mh = JSON_Message_Handler("lint", options.json) else: mh = Message_Handler("lint") mh.show_context = not options.brief mh.show_style = False mh.show_checks = True mh.autofix = False lint_backend = MH_Lint(options) command_line.execute(mh, options, {}, lint_backend)
def main_handler(): clp = command_line.create_basic_clp() clp["output_options"].add_argument( "--json", default="mh_trace.json", help="name of the JSON report (by default mh_trace.json)") clp["output_options"].add_argument( "--by-tag", action="store_true", default=False, help=("group tracing information by tag; by default we group by" " unit name first")) options = command_line.parse_args(clp) mh = Message_Handler("trace") mh.show_context = not options.brief mh.show_style = False mh.show_checks = False mh.autofix = False trace_backend = MH_Trace(options) command_line.execute(mh, options, {}, trace_backend, process_tests=True)
def main(): # pylint: disable=import-outside-toplevel from argparse import ArgumentParser # pylint: enable=import-outside-toplevel ap = ArgumentParser() ap.add_argument("name", metavar="FILE|DIR") options = ap.parse_args() mh = Message_Handler("debug") mh.sort_messages = False mh.colour = False if os.path.isfile(options.name): sanity_test(mh, options.name, options) elif os.path.isdir(options.name): for path, _, files in os.walk(options.name): for f in files: if f.endswith(".slx"): sanity_test(mh, os.path.join(path, f), options) else: ap.error("%s is neither a file or directory" % options.name) print() print("=== Summary of misc. children ===") for block_type in sorted(anatomy): print("Children in %s" % block_type) for tag in sorted(anatomy[block_type]): print(" * %s" % tag) mh.summary_and_exit()
def main_handler(): clp = command_line.create_basic_clp() clp["debug_options"].add_argument( "--keep", help="do not delete intermediate files", action="store_true", default=False) options = command_line.parse_args(clp) try: subprocess.run(["cbmc", "--version"], check=True, capture_output=True, encoding="utf-8") except FileNotFoundError: clp["ap"].error("MH BMC needs 'cbmc' from the CPROVER tools on " "your PATH") mh = Message_Handler("bmc") mh.show_context = not options.brief mh.show_style = False mh.show_checks = True mh.autofix = False bmc_backend = MH_BMC(options) command_line.execute(mh, options, {}, bmc_backend)
def cfg_parser_main(): # pylint: disable=import-outside-toplevel from argparse import ArgumentParser # pylint: enable=import-outside-toplevel ap = ArgumentParser() ap.add_argument("file") ap.add_argument("--no-tb", action="store_true", default=False, help="Do not show debug-style backtrace") options = ap.parse_args() mh = Message_Handler("debug") mh.sort_messages = False mh.colour = False sanity_test(mh, options.file, not options.no_tb) mh.summary_and_exit()
def main_handler(): clp = command_line.create_basic_clp() clp["output_options"].add_argument( "--worst-offenders", default=10, type=int, help=("Produce a table of the worst offenders for each metric." " By default this is 10; setting it to 0 disables this" " feature.")) clp["output_options"].add_argument( "--ci", default=False, action="store_true", help=("Do not print any metrics report, only notify about violations." "This is the intended way to run in a CI environment.")) clp["output_options"].add_argument( "--text", default=None, metavar="FILE", help=("Print plain-text metrics summary to the given file. By" " default we print the summary to standard output.")) clp["output_options"].add_argument( "--html", default=None, metavar="FILE", help=("Write HTML metrics report to the file.")) clp["output_options"].add_argument( "--portable-html", default=False, action="store_true", help=("Use assets/stylesheets from the web instead of " "the local MISS_HIT install.")) clp["output_options"].add_argument( "--json", default=None, metavar="FILE", help=("Create JSON metrics report in the given file.")) options = command_line.parse_args(clp) if options.text: if os.path.exists(options.text) and not os.path.isfile(options.text): clp["ap"].error("cannot write metrics to %s, it exists and is" " not a file" % options.text) if options.html or options.json: clp["ap"].error("the text option is mutually exclusive with other" " output options") if options.html: if os.path.exists(options.html) and not os.path.isfile(options.html): clp["ap"].error("cannot write metrics to %s, it exists and is" " not a file" % options.text) if options.text or options.json: clp["ap"].error("the html option is mutually exclusive with other" " output options") if options.json: if os.path.exists(options.json) and not os.path.isfile(options.json): clp["ap"].error("cannot write metrics to %s, it exists and is" " not a file" % options.text) if options.text or options.html: clp["ap"].error("the json option is mutually exclusive with other" " output options") if options.ci and (options.text or options.html or options.json): clp["ap"].error("the CI mode and and text/html/json options are" "mutually exclusive") if options.worst_offenders < 0: clp["ap"].error("the worst-offender option cannot be negative") mh = Message_Handler("metric") mh.show_context = not options.brief mh.show_style = False mh.autofix = False metric_backend = MH_Metric(options) command_line.execute(mh, options, {}, metric_backend)
def main_handler(): rule_set = get_rules() clp = command_line.create_basic_clp() clp["ap"].add_argument("--fix", action="store_true", default=False, help=("Automatically fix issues where the fix" " is obvious")) clp["ap"].add_argument("--process-slx", action="store_true", default=False, help=("Style-check (but not yet auto-fix) code" " inside SIMULINK models. This option is" " temporary, and will be removed in" " future once the feature is good enough" " to be enabled by default.")) # Extra output options clp["output_options"].add_argument( "--html", default=None, help="Write report to given file as HTML") clp["output_options"].add_argument("--json", default=None, help="Produce JSON report") clp["output_options"].add_argument( "--no-style", action="store_true", default=False, help="Don't show any style message, only show warnings and errors.") # Debug options clp["debug_options"].add_argument( "--debug-dump-tree", default=None, metavar="FILE", help="Dump text-based parse tree to given file") clp["debug_options"].add_argument("--debug-validate-links", action="store_true", default=False, help="Debug option to check AST links") style_option = clp["ap"].add_argument_group("rule options") # Add any parameters from rules for rule_kind in rule_set: for rule in rule_set[rule_kind]: rule_params = getattr(rule, "parameters", None) if not rule_params: continue for p_name in rule_params: style_option.add_argument("--" + p_name, **rule_params[p_name]) style_option.add_argument("--copyright-entity", metavar="STR", default=[], nargs="+", help=("Add (company) name to check for in " "Copyright notices. Can be specified " "multiple times.")) options = command_line.parse_args(clp) if options.html: if options.json: clp["ap"].error("Cannot produce JSON and HTML at the same time") if os.path.exists(options.html) and not os.path.isfile(options.html): clp["ap"].error("Cannot write to %s: it is not a file" % options.html) mh = HTML_Message_Handler("style", options.html) elif options.json: if os.path.exists(options.json) and not os.path.isfile(options.json): clp["ap"].error("Cannot write to %s: it is not a file" % options.json) mh = JSON_Message_Handler("style", options.json) else: mh = Message_Handler("style") mh.show_context = not options.brief mh.show_style = not options.no_style mh.autofix = options.fix extra_options = { "fd_tree": None, "rule_set": rule_set, } if options.debug_dump_tree: extra_options["fd_tree"] = open(options.debug_dump_tree, "w") style_backend = MH_Style() command_line.execute(mh, options, extra_options, style_backend, options.process_slx) if options.debug_dump_tree: extra_options["fd_tree"].close()
def main_handler(): clp = command_line.create_basic_clp( epilog=("Remember to carefully review any code changes this tool" " makes, as copyright notices are generally considered to" " be quite important.")) clp["ap"].add_argument("--process-slx", action="store_true", default=False, help=("Update copyright notices inside Simulink" " models. This option is temporary, and" " will be removed in future once the" " feature is good enough to be enabled" " by default.")) c_actions = clp["ap"].add_argument_group("copyright action") c_actions = c_actions.add_mutually_exclusive_group(required=True) c_actions.add_argument("--update-year", action="store_true", default=False, help=("Update the end year in copyright notices for" " the primary copyright holder to the current" " year.")) c_actions.add_argument("--merge", action="store_true", default=False, help=("Merge all non-3rd party copyright notices" " into one for the primary copyright holder")) c_actions.add_argument("--change-entity", default=None, metavar="OLD_COPYRIGHT_HOLDER", help=("Change notices from the specified copyright" " holder into the primary copyright holder.")) c_actions.add_argument("--add-notice", action="store_true", default=False, help=("Add a copyright notice to files that do not" " have one yet.")) c_data = clp["ap"].add_argument_group("copyright data") c_data.add_argument("--year", default=datetime.datetime.now().year, type=int, help=("The current year (by default this is" " %(default)s)")) c_data.add_argument("--primary-entity", default=None, metavar="COPYRIGHT_HOLDER", help=("The primary copyright entity.")) c_data.add_argument("--template-range", default="(c) Copyright %(ystart)u-%(yend)u %(org)s", metavar="TEMPLATE_TEXT", help=("Text template to use for a copyright notice" " with a year range. default: '%(default)s'")) c_data.add_argument("--template", default="(c) Copyright %(yend)u %(org)s", metavar="TEMPLATE_TEXT", help=("Text template to use for a copyright notice" " with a single year. default: '%(default)s'")) options = command_line.parse_args(clp) # Sanity check year if options.year < 1900: # pragma: no cover clp["ap"].error("year must be at lest 1900") elif options.year >= 10000: # pragma: no cover clp["ap"].error("I am extremely concerned that this tool is still" " useful after 8000 years, stop what you're doing" " and change programming language NOW.") mh = Message_Handler("copyright") mh.show_context = not options.brief mh.show_style = False mh.show_checks = False mh.autofix = True copyright_backend = MH_Copyright() command_line.execute(mh, options, {}, copyright_backend, options.process_slx)
def main(): ap = argparse.ArgumentParser() ap.add_argument("file_before") ap.add_argument("file_after") ap.add_argument("--kdiff3", help="Use KDiff3 to show a visual diff", action="store_true", default=False) ap.add_argument("--allow-weird-names", help=("Permit file names not ending in .slx (use at " "your own risk)"), action="store_true", default=False) options = ap.parse_args() for item in (options.file_before, options.file_after): if not os.path.isfile(item): ap.error("%s is not a file" % item) elif not item.endswith(".slx") and not options.allow_weird_names: ap.error("%s is not a modern (slx) Simulink model") mh = Message_Handler("diff") n_before = load_file(mh, options.file_before) n_after = load_file(mh, options.file_after) code_blocks = {} for side in ("before", "after"): n_root = n_before if side == "before" else n_after for n_block in n_root.iter_all_blocks(): if not isinstance(n_block, s_ast.Matlab_Function): continue name = n_block.local_name() if name not in code_blocks: code_blocks[name] = {"before": None, "after": None} code_blocks[name][side] = n_block.get_text() first = True for name in sorted(code_blocks): before = code_blocks[name]["before"] after = code_blocks[name]["after"] if before == after: continue if first: first = False else: print() print("Difference in MATLAB Code block '%s'" % name) if before is None: if options.kdiff3: with tempfile.TemporaryDirectory() as dirname: with open(os.path.join(dirname, "before"), "w") as fd: pass with open(os.path.join(dirname, "after"), "w") as fd: fd.write(after) cmd = "kdiff3 %s %s" % (os.path.join( dirname, "before"), os.path.join(dirname, "after")) os.system(cmd) else: print("NEW block containing:") print("=" * 78) print(before) print("=" * 78) elif after is None: print("DELETED block") else: if options.kdiff3: with tempfile.TemporaryDirectory() as dirname: with open(os.path.join(dirname, "before"), "w") as fd: fd.write(before) with open(os.path.join(dirname, "after"), "w") as fd: fd.write(after) cmd = "kdiff3 %s %s" % (os.path.join( dirname, "before"), os.path.join(dirname, "after")) os.system(cmd) else: print("CHANGED block:") print("=" * 78) print("\n".join( difflib.unified_diff(before.splitlines(), after.splitlines(), fromfile=options.file_before, tofile=options.file_after))) print("=" * 78) return 0