diff --git a/lib/library.cpp b/lib/library.cpp index 57b89917172..ae780f0ffe0 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -87,12 +87,15 @@ Library::Error Library::load(const char exename[], const char path[], bool debug return Error(); } + const bool is_abs_path = Path::isAbsolute(path); + std::string absolute_path; // open file.. tinyxml2::XMLDocument doc; if (debug) std::cout << "looking for library '" + std::string(path) + "'" << std::endl; tinyxml2::XMLError error = doc.LoadFile(path); + // TODO: do not ignore read errors if (error == tinyxml2::XML_ERROR_FILE_READ_ERROR && Path::getFilenameExtension(path).empty()) { // Reading file failed, try again... @@ -110,27 +113,31 @@ Library::Error Library::load(const char exename[], const char path[], bool debug absolute_path = Path::getAbsoluteFilePath(fullfilename); } - std::list cfgfolders; -#ifdef FILESDIR - cfgfolders.emplace_back(FILESDIR "/cfg"); -#endif - if (exename) { - const std::string exepath(Path::fromNativeSeparators(Path::getPathFromFilename(Path::getCurrentExecutablePath(exename)))); - cfgfolders.push_back(exepath + "cfg"); - cfgfolders.push_back(exepath + "../cfg"); - cfgfolders.push_back(exepath); - } + // only perform further lookups when the given path was not absolute + if (!is_abs_path && error == tinyxml2::XML_ERROR_FILE_NOT_FOUND) + { + std::list cfgfolders; + #ifdef FILESDIR + cfgfolders.emplace_back(FILESDIR "/cfg"); + #endif + if (exename) { + const std::string exepath(Path::fromNativeSeparators(Path::getPathFromFilename(Path::getCurrentExecutablePath(exename)))); + cfgfolders.push_back(exepath + "cfg"); + cfgfolders.push_back(exepath + "../cfg"); + cfgfolders.push_back(exepath); + } - while (error == tinyxml2::XML_ERROR_FILE_NOT_FOUND && !cfgfolders.empty()) { - const std::string cfgfolder(cfgfolders.back()); - cfgfolders.pop_back(); - const char *sep = (!cfgfolder.empty() && endsWith(cfgfolder,'/') ? "" : "/"); - const std::string filename(cfgfolder + sep + fullfilename); - if (debug) - std::cout << "looking for library '" + std::string(filename) + "'" << std::endl; - error = doc.LoadFile(filename.c_str()); - if (error != tinyxml2::XML_ERROR_FILE_NOT_FOUND) - absolute_path = Path::getAbsoluteFilePath(filename); + while (error == tinyxml2::XML_ERROR_FILE_NOT_FOUND && !cfgfolders.empty()) { + const std::string cfgfolder(cfgfolders.back()); + cfgfolders.pop_back(); + const char *sep = (!cfgfolder.empty() && endsWith(cfgfolder,'/') ? "" : "/"); + const std::string filename(cfgfolder + sep + fullfilename); + if (debug) + std::cout << "looking for library '" + std::string(filename) + "'" << std::endl; + error = doc.LoadFile(filename.c_str()); + if (error != tinyxml2::XML_ERROR_FILE_NOT_FOUND) + absolute_path = Path::getAbsoluteFilePath(filename); + } } } else absolute_path = Path::getAbsoluteFilePath(path); diff --git a/test/cli/other_test.py b/test/cli/other_test.py index f497459ea82..95199c15fc5 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -10,7 +10,6 @@ def __remove_std_lookup_log(l : list, exepath): - print(l) l.remove("looking for library 'std.cfg'") l.remove("looking for library '{}/std.cfg'".format(exepath)) l.remove("looking for library '{}/../cfg/std.cfg'".format(exepath)) @@ -1570,3 +1569,48 @@ def test_lib_lookup_notfound(tmpdir): "library not found: 'none'", "cppcheck: Failed to load library configuration file 'none'. File not found" ] + + +def test_lib_lookup_absolute(tmpdir): + test_file = os.path.join(tmpdir, 'test.c') + with open(test_file, 'wt'): + pass + + cfg_file = os.path.join(tmpdir, 'test.cfg') + with open(cfg_file, 'wt') as f: + f.write(''' + + + + ''') + + exitcode, stdout, _, exe = cppcheck_ex(['--library={}'.format(cfg_file), '--debug-lookup', test_file]) + exepath = os.path.dirname(exe) + if sys.platform == 'win32': + exepath = exepath.replace('\\', '/') + assert exitcode == 0, stdout + lines = __remove_std_lookup_log(stdout.splitlines(), exepath) + assert lines == [ + "looking for library '{}'".format(cfg_file), + 'Checking {} ...'.format(test_file) + ] + + +def test_lib_lookup_absolute_notfound(tmpdir): + test_file = os.path.join(tmpdir, 'test.c') + with open(test_file, 'wt'): + pass + + cfg_file = os.path.join(tmpdir, 'test.cfg') + + exitcode, stdout, _, exe = cppcheck_ex(['--library={}'.format(cfg_file), '--debug-lookup', test_file]) + exepath = os.path.dirname(exe) + if sys.platform == 'win32': + exepath = exepath.replace('\\', '/') + assert exitcode == 1, stdout + lines = __remove_std_lookup_log(stdout.splitlines(), exepath) + assert lines == [ + "looking for library '{}'".format(cfg_file), + "library not found: '{}'".format(cfg_file), + "cppcheck: Failed to load library configuration file '{}'. File not found".format(cfg_file) + ]