def main(args): """ Execute a wrapper over log-analyze-parse, aka 'check'. """ logger.setup_logger(args.verbose if 'verbose' in args else None) def __update_if_key_exists(source, target, key): """Append the source Namespace's element with 'key' to target with the same key, but only if it exists.""" if key in source: setattr(target, key, getattr(source, key)) if 'force' in args: LOG.warning('"--force" option has been deprecated and it will be ' 'removed in the future version of CodeChecker. Use the ' '"--clean" option to delete analysis reports stored in ' 'the output directory.') # If no output directory is given then the checker results go to a # temporary directory. This way the subsequent "quick" checks don't pollute # the result list of a previous check. If the detection status function is # intended to be used (i.e. by keeping the .plist files) then the output # directory has to be provided explicitly. is_temp_output = False if 'output_dir' in args: output_dir = args.output_dir else: output_dir = tempfile.mkdtemp() is_temp_output = True output_dir = os.path.abspath(output_dir) if not os.path.exists(output_dir): os.makedirs(output_dir) logfile = None is_command = False try: # --- Step 1.: Perform logging if build command was specified. if 'command' in args: logfile = tempfile.NamedTemporaryFile().name is_command = True # Translate the argument list between check and log. log_args = argparse.Namespace(command=args.command, logfile=logfile) __update_if_key_exists(args, log_args, 'quiet') __update_if_key_exists(args, log_args, 'verbose') import codechecker_analyzer.cmd.log as log_module LOG.debug("Calling LOG with args:") LOG.debug(log_args) log_module.main(log_args) elif 'logfile' in args: logfile = args.logfile # --- Step 2.: Perform the analysis. if not os.path.exists(logfile): raise OSError("The specified logfile '" + logfile + "' does not " "exist.") analyze_args = argparse.Namespace(logfile=[logfile], output_path=output_dir, output_format='plist', jobs=args.jobs) # Some arguments don't have default values. # We can't set these keys to None because it would result in an error # after the call. args_to_update = [ 'quiet', 'skipfile', 'analyzers', 'add_compiler_defaults', 'clangsa_args_cfg_file', 'tidy_args_cfg_file', 'tidy_config', 'capture_analysis_output', 'ctu_phases', 'stats_output', 'stats_dir', 'stats_enabled', 'stats_relevance_threshold', 'stats_min_sample_count', 'enable_all', 'ordered_checkers', # --enable and --disable. 'timeout', 'compile_uniqueing', 'report_hash', 'enable_z3', 'enable_z3_refutation' ] for key in args_to_update: __update_if_key_exists(args, analyze_args, key) if 'clean' in args: setattr(analyze_args, 'clean', True) __update_if_key_exists(args, analyze_args, 'verbose') import codechecker_analyzer.cmd.analyze as analyze_module LOG.debug("Calling ANALYZE with args:") LOG.debug(analyze_args) analyze_module.main(analyze_args) # --- Step 3.: Print to stdout. parse_args = argparse.Namespace(input=[output_dir], input_format='plist') __update_if_key_exists(args, parse_args, 'print_steps') __update_if_key_exists(args, parse_args, 'verbose') __update_if_key_exists(args, parse_args, 'skipfile') import codechecker_analyzer.cmd.parse as parse_module LOG.debug("Calling PARSE with args:") LOG.debug(parse_args) parse_module.main(parse_args) except ImportError: LOG.error("Check failed: couldn't import a library.") except Exception: LOG.exception("Running check failed.") import traceback traceback.print_exc() finally: if is_temp_output: shutil.rmtree(output_dir) if is_command: os.remove(logfile) LOG.debug("Check finished.")
def main(args): """ Execute a wrapper over log-analyze-parse, aka 'check'. """ logger.setup_logger(args.verbose if 'verbose' in args else None) if 'ctu_ast_mode' in args and 'ctu_phases' not in args: LOG.error("Analyzer option 'ctu-ast-mode' requires CTU mode enabled") sys.exit(1) def __update_if_key_exists(source, target, key): """Append the source Namespace's element with 'key' to target with the same key, but only if it exists.""" if key in source: setattr(target, key, getattr(source, key)) # If no output directory is given then the checker results go to a # temporary directory. This way the subsequent "quick" checks don't pollute # the result list of a previous check. If the detection status function is # intended to be used (i.e. by keeping the .plist files) then the output # directory has to be provided explicitly. if 'output_dir' in args: output_dir = args.output_dir else: output_dir = tempfile.mkdtemp() output_dir = os.path.abspath(output_dir) if not os.path.exists(output_dir): os.makedirs(output_dir) logfile = None try: # --- Step 1.: Perform logging if build command was specified. if 'command' in args: logfile = tempfile.NamedTemporaryFile().name # Translate the argument list between check and log. log_args = argparse.Namespace(command=args.command, logfile=logfile) __update_if_key_exists(args, log_args, 'quiet') __update_if_key_exists(args, log_args, 'verbose') import codechecker_analyzer.cmd.log as log_module LOG.debug("Calling LOG with args:") LOG.debug(log_args) # If not explicitly given the debug log file of ld_logger is placed # in report directory if any. Otherwise parallel "CodeChecker # check" commands would overwrite each other's log files under /tmp # which is the default location for "CodeChecker check". if 'CC_LOGGER_DEBUG_FILE' not in os.environ: os.environ['CC_LOGGER_DEBUG_FILE'] = \ os.path.join(output_dir, 'codechecker.logger.debug') log_module.main(log_args) elif 'logfile' in args: logfile = args.logfile # --- Step 2.: Perform the analysis. analyze_args = argparse.Namespace( logfile=logfile, output_path=output_dir, output_format='plist', jobs=args.jobs, keep_gcc_include_fixed=args.keep_gcc_include_fixed, keep_gcc_intrin=args.keep_gcc_intrin) # Some arguments don't have default values. # We can't set these keys to None because it would result in an error # after the call. args_to_update = [ 'quiet', 'skipfile', 'files', 'analyzers', 'add_compiler_defaults', 'clangsa_args_cfg_file', 'tidy_args_cfg_file', 'tidy_config', 'analyzer_config', 'checker_config', 'capture_analysis_output', 'config_file', 'ctu_phases', 'ctu_reanalyze_on_failure', 'stats_output', 'stats_dir', 'stats_enabled', 'stats_relevance_threshold', 'stats_min_sample_count', 'enable_all', 'ordered_checkers', # --enable and --disable. 'timeout', 'compile_uniqueing', 'report_hash', 'enable_z3', 'enable_z3_refutation' ] for key in args_to_update: __update_if_key_exists(args, analyze_args, key) if 'clean' in args: setattr(analyze_args, 'clean', True) __update_if_key_exists(args, analyze_args, 'verbose') import codechecker_analyzer.cmd.analyze as analyze_module LOG.debug("Calling ANALYZE with args:") LOG.debug(analyze_args) analysis_exit_status = analyze_module.main(analyze_args) # --- Step 3.: Print to stdout. parse_args = argparse.Namespace(input=[output_dir], input_format='plist') __update_if_key_exists(args, parse_args, 'print_steps') __update_if_key_exists(args, parse_args, 'review_status') __update_if_key_exists(args, parse_args, 'verbose') __update_if_key_exists(args, parse_args, 'skipfile') __update_if_key_exists(args, parse_args, 'suppress') import codechecker_analyzer.cmd.parse as parse_module LOG.debug("Calling PARSE with args:") LOG.debug(parse_args) parse_module.main(parse_args) except ImportError: LOG.error("Check failed: couldn't import a library.") except Exception: LOG.exception("Running check failed.") import traceback traceback.print_exc() finally: if 'output_dir' not in args: shutil.rmtree(output_dir) if 'command' in args: os.remove(logfile) LOG.debug("Check finished.") return analysis_exit_status
def main(args): """ Execute a wrapper over log-analyze-parse, aka 'check'. """ logger.setup_logger(args.verbose if 'verbose' in args else None) def __update_if_key_exists(source, target, key): """Append the source Namespace's element with 'key' to target with the same key, but only if it exists.""" if key in source: setattr(target, key, getattr(source, key)) # If no output directory is given then the checker results go to a # temporary directory. This way the subsequent "quick" checks don't pollute # the result list of a previous check. If the detection status function is # intended to be used (i.e. by keeping the .plist files) then the output # directory has to be provided explicitly. is_temp_output = False if 'output_dir' in args: output_dir = args.output_dir else: output_dir = tempfile.mkdtemp() is_temp_output = True output_dir = os.path.abspath(output_dir) if not os.path.exists(output_dir): os.makedirs(output_dir) logfile = None is_command = False try: # --- Step 1.: Perform logging if build command was specified. if 'command' in args: logfile = tempfile.NamedTemporaryFile().name is_command = True # Translate the argument list between check and log. log_args = argparse.Namespace( command=args.command, logfile=logfile ) __update_if_key_exists(args, log_args, 'quiet') __update_if_key_exists(args, log_args, 'verbose') import codechecker_analyzer.cmd.log as log_module LOG.debug("Calling LOG with args:") LOG.debug(log_args) log_module.main(log_args) elif 'logfile' in args: logfile = args.logfile # --- Step 2.: Perform the analysis. if not os.path.exists(logfile): raise OSError("The specified logfile '" + logfile + "' does not " "exist.") analyze_args = argparse.Namespace( logfile=[logfile], output_path=output_dir, output_format='plist', jobs=args.jobs ) # Some arguments don't have default values. # We can't set these keys to None because it would result in an error # after the call. args_to_update = ['quiet', 'skipfile', 'analyzers', 'add_compiler_defaults', 'clangsa_args_cfg_file', 'tidy_args_cfg_file', 'tidy_config', 'capture_analysis_output', 'ctu_phases', 'stats_output', 'stats_dir', 'stats_enabled', 'stats_relevance_threshold', 'stats_min_sample_count', 'enable_all', 'ordered_checkers', # --enable and --disable. 'timeout', 'compile_uniqueing', 'report_hash' ] for key in args_to_update: __update_if_key_exists(args, analyze_args, key) if 'force' in args or 'clean' in args: setattr(analyze_args, 'clean', True) __update_if_key_exists(args, analyze_args, 'verbose') import codechecker_analyzer.cmd.analyze as analyze_module LOG.debug("Calling ANALYZE with args:") LOG.debug(analyze_args) analyze_module.main(analyze_args) # --- Step 3.: Print to stdout. parse_args = argparse.Namespace( input=[output_dir], input_format='plist' ) __update_if_key_exists(args, parse_args, 'print_steps') __update_if_key_exists(args, parse_args, 'verbose') __update_if_key_exists(args, parse_args, 'skipfile') import codechecker_analyzer.cmd.parse as parse_module LOG.debug("Calling PARSE with args:") LOG.debug(parse_args) parse_module.main(parse_args) except ImportError: LOG.error("Check failed: couldn't import a library.") except Exception as ex: LOG.exception("Running check failed.") import traceback traceback.print_exc() finally: if is_temp_output: shutil.rmtree(output_dir) if is_command: os.remove(logfile) LOG.debug("Check finished.")