1#!/usr/bin/env python3 2 3import sys, re, os 4 5module_dir = os.path.dirname(os.path.realpath(__file__)) 6xen_dir = os.path.realpath(module_dir + "/../..") 7repo_dir = os.path.realpath(xen_dir + "/..") 8tools_dir = os.path.realpath(xen_dir + "/tools") 9 10step_get_make_vars = False 11step_parse_tags = True 12step_cppcheck_deps = False 13step_build_xen = True 14step_cppcheck_report = False 15step_clean_analysis = True 16step_distclean_analysis = False 17 18target_build = False 19target_clean = False 20target_distclean = False 21 22analysis_tool = "" 23cppcheck_binpath = "cppcheck" 24cppcheck_html = False 25cppcheck_htmlreport_binpath = "cppcheck-htmlreport" 26cppcheck_misra = False 27cppcheck_skip_rules = "" 28make_forward_args = "" 29outdir = xen_dir 30 31 32def help(): 33 msg=""" 34Usage: {} [OPTION] ... [-- [make arguments]] 35 36This script runs the analysis on the Xen codebase. 37 38The phases for the analysis are <tags>, <build>, <clean>, <cppcheck report> 39 40Depending on the options below, only some phases will run: 41 42<no options>: tags, build, [cppcheck report], clean 43--build-only: build, [cppcheck report] 44--clean-only: clean 45--distclean: clean, [destroy cppcheck report] 46--no-build: tags, clean 47--no-clean: tags, build 48 49--no-build/--no-clean can be passed together to avoid both clean and build 50phases. 51Tags and build phases need to specify --run-coverity, --run-eclair or 52--run-cppcheck. 53Cppcheck report creation phase runs only when --run-cppcheck is passed to the 54script. 55 56Options: 57 --build-only Run only the commands to build Xen with the optional 58 make arguments passed to the script 59 --clean-only Run only the commands to clean the analysis artifacts 60 --cppcheck-bin= Path to the cppcheck binary (Default: {}) 61 --cppcheck-html Produce an additional HTML output report for Cppcheck 62 --cppcheck-html-bin= Path to the cppcheck-html binary (Default: {}) 63 --cppcheck-misra Activate the Cppcheck MISRA analysis 64 --cppcheck-skip-rules= List of MISRA rules to be skipped, comma separated. 65 (e.g. --cppcheck-skip-rules=1.1,20.7,8.4) 66 --distclean Clean analysis artifacts and reports 67 -h, --help Print this help 68 --no-build Skip the build Xen phase 69 --no-clean Don\'t clean the analysis artifacts on exit 70 --run-coverity Run the analysis for the Coverity tool 71 --run-cppcheck Run the Cppcheck analysis tool on Xen 72 --run-eclair Run the analysis for the Eclair tool 73""" 74 print(msg.format(sys.argv[0], cppcheck_binpath, 75 cppcheck_htmlreport_binpath)) 76 77 78def parse_commandline(argv): 79 global analysis_tool 80 global cppcheck_binpath 81 global cppcheck_html 82 global cppcheck_htmlreport_binpath 83 global cppcheck_misra 84 global cppcheck_skip_rules 85 global make_forward_args 86 global outdir 87 global step_get_make_vars 88 global step_parse_tags 89 global step_cppcheck_deps 90 global step_build_xen 91 global step_cppcheck_report 92 global step_clean_analysis 93 global step_distclean_analysis 94 global target_build 95 global target_clean 96 global target_distclean 97 forward_to_make = False 98 for option in argv: 99 args_with_content_regex = re.match(r'^(--[a-z]+[a-z-]*)=(.*)$', option) 100 101 if forward_to_make: 102 # Intercept outdir 103 outdir_regex = re.match("^O=(.*)$", option) 104 if outdir_regex: 105 outdir = outdir_regex.group(1) 106 # Forward any make arguments 107 make_forward_args = make_forward_args + " " + option 108 elif option == "--build-only": 109 target_build = True 110 elif option == "--clean-only": 111 target_clean = True 112 elif args_with_content_regex and \ 113 args_with_content_regex.group(1) == "--cppcheck-bin": 114 cppcheck_binpath = args_with_content_regex.group(2) 115 elif option == "--cppcheck-html": 116 cppcheck_html = True 117 elif args_with_content_regex and \ 118 args_with_content_regex.group(1) == "--cppcheck-html-bin": 119 cppcheck_htmlreport_binpath = args_with_content_regex.group(2) 120 elif option == "--cppcheck-misra": 121 cppcheck_misra = True 122 elif args_with_content_regex and \ 123 args_with_content_regex.group(1) == "--cppcheck-skip-rules": 124 cppcheck_skip_rules = args_with_content_regex.group(2) 125 elif option == "--distclean": 126 target_distclean = True 127 elif (option == "--help") or (option == "-h"): 128 help() 129 sys.exit(0) 130 elif option == "--no-build": 131 step_build_xen = False 132 elif option == "--no-clean": 133 step_clean_analysis = False 134 elif (option == "--run-coverity") or (option == "--run-eclair"): 135 analysis_tool = option[6:] 136 elif (option == "--run-cppcheck"): 137 analysis_tool = "cppcheck" 138 step_get_make_vars = True 139 step_cppcheck_deps = True 140 step_cppcheck_report = True 141 elif option == "--": 142 forward_to_make = True 143 else: 144 print("Invalid option: {}".format(option)) 145 help() 146 sys.exit(1) 147 148 if target_build and (target_clean or target_distclean): 149 print("--build-only is not compatible with --clean-only/--distclean " 150 "argument.") 151 sys.exit(1) 152 153 if target_distclean: 154 # Implicit activation of clean target 155 target_clean = True 156 157 step_distclean_analysis = True 158 159 if target_clean: 160 step_get_make_vars = False 161 step_parse_tags = False 162 step_cppcheck_deps = False 163 step_build_xen = False 164 step_cppcheck_report = False 165 step_clean_analysis = True 166 return 167 168 if analysis_tool == "": 169 print("Please specify one analysis tool.") 170 help() 171 sys.exit(1) 172 173 if target_build: 174 step_parse_tags = False 175 step_build_xen = True 176 step_clean_analysis = False 177