diff --git a/addons/cppcheckdata.py b/addons/cppcheckdata.py index 8fdeffaea..5582a5b63 100755 --- a/addons/cppcheckdata.py +++ b/addons/cppcheckdata.py @@ -1206,12 +1206,30 @@ def ArgumentParser(): parser.add_argument("--cli", help="Addon is executed from Cppcheck", action="store_true") + parser.add_argument("--file-list", metavar='', + default=None, + help="file list in a text file") parser.add_argument("-q", "--quiet", help='do not print "Checking ..." lines', action="store_true") return parser +def get_files(args): + """Return dump_files, ctu_info_files""" + dump_files = args.dumpfile + ctu_info_files = [] + if args.file_list: + with open(args.file_list, 'rt') as f: + for line in f.readlines(): + line = line.rstrip() + if line.endswith('.ctu-info'): + ctu_info_files.append(line) + else: + dump_files.append(line) + return dump_files, ctu_info_files + + def simpleMatch(token, pattern): for p in pattern.split(' '): if not token or token.str != p: diff --git a/addons/misra.py b/addons/misra.py index d4064abeb..384196b06 100755 --- a/addons/misra.py +++ b/addons/misra.py @@ -3437,16 +3437,14 @@ class MisraChecker: # 22.4 is already covered by Cppcheck writeReadOnlyFile self.executeCheck(2205, self.misra_22_5, cfg) - def analyse_ctu_info(self, files): + def analyse_ctu_info(self, ctu_info_files): all_typedef_info = [] all_tagname_info = [] all_macro_info = [] from cppcheckdata import Location - for filename in files: - if not filename.endswith('.ctu-info'): - continue + for filename in ctu_info_files: for line in open(filename, 'rt'): if not line.startswith('{'): continue @@ -3593,7 +3591,9 @@ def main(): if args.file_prefix: checker.setFilePrefix(args.file_prefix) - if not args.dumpfile: + dump_files, ctu_info_files = cppcheckdata.get_files(args) + + if (not dump_files) and (not ctu_info_files): if not args.quiet: print("No input files.") sys.exit(0) @@ -3601,10 +3601,7 @@ def main(): if args.severity: checker.setSeverity(args.severity) - for item in args.dumpfile: - if item.endswith('.ctu-info'): - continue - + for item in dump_files: checker.parseDump(item) if settings.verify: @@ -3628,7 +3625,7 @@ def main(): if exitCode != 0: sys.exit(exitCode) - checker.analyse_ctu_info(args.dumpfile) + checker.analyse_ctu_info(ctu_info_files) if settings.verify: sys.exit(exitCode) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index fc8072ee9..4d2e077cb 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -57,6 +57,8 @@ static const char Version[] = CPPCHECK_VERSION_STRING; static const char ExtraVersion[] = ""; +static const char FILELIST[] = "cppcheck-addon-ctu-file-list"; + static TimerResults s_timerResults; // CWE ids used @@ -260,7 +262,7 @@ static void createDumpFile(const Settings& settings, static std::string executeAddon(const AddonInfo &addonInfo, const std::string &defaultPythonExe, - const std::vector &files, + const std::string &file, std::function,std::string,std::string*)> executeCommand) { const std::string redirect = "2>&1"; @@ -288,9 +290,9 @@ static std::string executeAddon(const AddonInfo &addonInfo, throw InternalError(nullptr, "Failed to auto detect python"); } - std::string args = cmdFileName(addonInfo.scriptFile) + " --cli" + addonInfo.args; - for (const std::string& filename: files) - args += " " + cmdFileName(filename); + const std::string fileArg = (endsWith(file, FILELIST, sizeof(FILELIST)-1) ? " --file-list " : " ") + cmdFileName(file); + const std::string args = cmdFileName(addonInfo.scriptFile) + " --cli" + addonInfo.args + fileArg; + std::string result; if (!executeCommand(pythonExe, split(args), redirect, &result)) throw InternalError(nullptr, "Failed to execute addon (command: '" + pythonExe + " " + args + "')"); @@ -1304,6 +1306,16 @@ void CppCheck::executeAddons(const std::vector& files) if (mSettings.addons.empty() || files.empty()) return; + std::string fileList; + + if (files.size() >= 2 || endsWith(files[0], ".ctu-info", 9)) + { + fileList = Path::getPathFromFilename(files[0]) + FILELIST; + std::ofstream fout(fileList); + for (const std::string& f: files) + fout << f << std::endl; + } + for (const std::string &addon : mSettings.addons) { struct AddonInfo addonInfo; const std::string &failedToGetAddonInfo = addonInfo.getAddonInfo(addon, mSettings.exename); @@ -1316,7 +1328,7 @@ void CppCheck::executeAddons(const std::vector& files) continue; const std::string results = - executeAddon(addonInfo, mSettings.addonPython, files, mExecuteCommand); + executeAddon(addonInfo, mSettings.addonPython, fileList.empty() ? files[0] : fileList, mExecuteCommand); std::istringstream istr(results); std::string line;