From 08d41ab8af61cf20ac894e2160a06d8cb3c2076f Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 15 Mar 2019 06:59:37 +0100 Subject: [PATCH] Load std.cfg before all other libraries (#1740) - CLI: Save the libraries that should be loaded to a list and load them after the std.cfg has been loaded. - GUI: Load std.cfg (and windows.cfg / posix.cfg when applicable) before setting other options and loading the other libraries. In the project-file-dialog the std.cfg is searched first. If some other library fails to load is is retried with first loading std.cfg. - boost.cfg: Enable containers that depend on std containers. --- cfg/boost.cfg | 16 +++++++--------- cli/cmdlineparser.cpp | 4 ++-- cli/cppcheckexecutor.cpp | 11 +++++++++++ gui/mainwindow.cpp | 22 +++++++++++----------- gui/projectfiledialog.cpp | 31 ++++++++++++++++++++++++++++++- lib/settings.h | 5 ++++- 6 files changed, 65 insertions(+), 24 deletions(-) diff --git a/cfg/boost.cfg b/cfg/boost.cfg index 857d752b0..6f503779b 100644 --- a/cfg/boost.cfg +++ b/cfg/boost.cfg @@ -826,15 +826,13 @@ - - + + + + + + + diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 5161d48ad..37db84db8 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -532,8 +532,8 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) // --library else if (std::strncmp(argv[i], "--library=", 10) == 0) { - if (!CppCheckExecutor::tryLoadLibrary(mSettings->library, argv[0], argv[i]+10)) - return false; + std::string lib(argv[i] + 10); + mSettings->libraries.push_back(lib); } // --project diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 82cc960cb..230b95085 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -811,6 +811,17 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const cha Settings& settings = cppcheck.settings(); _settings = &settings; const bool std = tryLoadLibrary(settings.library, argv[0], "std.cfg"); + + for (const std::string &lib : settings.libraries) { + if (!tryLoadLibrary(settings.library, argv[0], lib.c_str())) { + const std::string msg("Failed to load the library " + lib); + const std::list callstack; + ErrorLogger::ErrorMessage errmsg(callstack, emptyString, Severity::information, msg, "failedToLoadCfg", false); + reportErr(errmsg); + return EXIT_FAILURE; + } + } + bool posix = true; if (settings.standards.posix) posix = tryLoadLibrary(settings.library, argv[0], "posix.cfg"); diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 78439ae3f..c03da51fc 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -827,6 +827,17 @@ Settings MainWindow::getCppcheckSettings() Settings result; + const bool std = tryLoadLibrary(&result.library, "std.cfg"); + bool posix = true; + if (result.standards.posix) + posix = tryLoadLibrary(&result.library, "posix.cfg"); + bool windows = true; + if (result.isWindowsPlatform()) + windows = tryLoadLibrary(&result.library, "windows.cfg"); + + if (!std || !posix || !windows) + QMessageBox::critical(this, tr("Error"), tr("Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir= at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured.").arg(!std ? "std.cfg" : !posix ? "posix.cfg" : "windows.cfg")); + // If project file loaded, read settings from it if (mProjectFile) { QStringList dirs = mProjectFile->getIncludeDirs(); @@ -920,17 +931,6 @@ Settings MainWindow::getCppcheckSettings() result.standards.posix = mSettings->value(SETTINGS_STD_POSIX, false).toBool(); result.enforcedLang = (Settings::Language)mSettings->value(SETTINGS_ENFORCED_LANGUAGE, 0).toInt(); - const bool std = tryLoadLibrary(&result.library, "std.cfg"); - bool posix = true; - if (result.standards.posix) - posix = tryLoadLibrary(&result.library, "posix.cfg"); - bool windows = true; - if (result.isWindowsPlatform()) - windows = tryLoadLibrary(&result.library, "windows.cfg"); - - if (!std || !posix || !windows) - QMessageBox::critical(this, tr("Error"), tr("Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir= at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured.").arg(!std ? "std.cfg" : !posix ? "posix.cfg" : "windows.cfg")); - if (result.jobs <= 1) { result.jobs = 1; } diff --git a/gui/projectfiledialog.cpp b/gui/projectfiledialog.cpp index 5381d1f93..ad27dad59 100644 --- a/gui/projectfiledialog.cpp +++ b/gui/projectfiledialog.cpp @@ -89,6 +89,30 @@ ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, QWidget *parent) if (!datadir.isEmpty()) searchPaths << datadir << datadir + "/cfg"; QStringList libs; + // Search the std.cfg first since other libraries could depend on it + QString stdLibraryFilename; + foreach (const QString sp, searchPaths) { + QDir dir(sp); + dir.setSorting(QDir::Name); + dir.setNameFilters(QStringList("*.cfg")); + dir.setFilter(QDir::Files | QDir::NoDotAndDotDot); + foreach (QFileInfo item, dir.entryInfoList()) { + QString library = item.fileName(); + if (library.compare("std.cfg", Qt::CaseInsensitive) != 0) + continue; + Library lib; + const QString fullfilename = sp + "/" + library; + const Library::Error err = lib.load(nullptr, fullfilename.toLatin1()); + if (err.errorcode != Library::OK) + continue; + // Working std.cfg found + stdLibraryFilename = fullfilename; + break; + } + if (!stdLibraryFilename.isEmpty()) + break; + } + // Search other libraries foreach (const QString sp, searchPaths) { QDir dir(sp); dir.setSorting(QDir::Name); @@ -99,7 +123,12 @@ ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, QWidget *parent) { Library lib; const QString fullfilename = sp + "/" + library; - const Library::Error err = lib.load(nullptr, fullfilename.toLatin1()); + Library::Error err = lib.load(nullptr, fullfilename.toLatin1()); + if (err.errorcode != Library::OK) { + // Some libraries depend on std.cfg so load it first and test again + lib.load(nullptr, stdLibraryFilename.toLatin1()); + err = lib.load(nullptr, fullfilename.toLatin1()); + } if (err.errorcode != Library::OK) continue; } diff --git a/lib/settings.h b/lib/settings.h index b90b05a2d..5d6290b4f 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -255,7 +255,10 @@ public: /** @brief --report-progress */ bool reportProgress; - /** Library (--library) */ + /** @brief --library= */ + std::list libraries; + + /** Library */ Library library; /** Rule */