From 796761d5820712833a6e4dc841f4a27bf8e500db Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 6 Apr 2011 16:30:23 +0200 Subject: [PATCH 1/9] Conditional inclusion of TinyXML source files in the CLI CMake script (bug #2679, #2524) The source files for the class library "TinyXML" will only be included into the build of the command line interface if the library "PCRE" was found before. Signed-off-by: Markus Elfring --- cli/CMakeLists.txt | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index d77726b3f..d968d96d4 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -1,24 +1,29 @@ # Minimal CMake build file to build cppcheck command line executable +include_directories("${CPPCHECK_SOURCE_DIR}/lib") + if(PCRE_FOUND) add_definitions(-DHAVE_RULES) - include_directories("${PCRE_INCLUDE_DIR}") + set(TINYXML_INCLUDE_DIR "${CPPCHECK_SOURCE_DIR}/externals/tinyxml/") + include_directories("${PCRE_INCLUDE_DIR}" "${TINYXML_INCLUDE_DIR}") set(CHECK_LIBS ${PCRE_LIBRARIES}) endif() -set(TINYXML_INCLUDE_DIR "${CPPCHECK_SOURCE_DIR}/externals/tinyxml/") - SET(CHECKCLI_SRCS cmdlineparser.cpp cppcheckexecutor.cpp filelister.cpp main.cpp - threadexecutor.cpp pathmatch.cpp - "${TINYXML_INCLUDE_DIR}tinystr.cpp" - "${TINYXML_INCLUDE_DIR}tinyxml.cpp" - "${TINYXML_INCLUDE_DIR}tinyxmlerror.cpp" - "${TINYXML_INCLUDE_DIR}tinyxmlparser.cpp") + threadexecutor.cpp) + +if(PCRE_FOUND) + set(CHECKCLI_SRCS ${CHECKCLI_SRCS} + "${TINYXML_INCLUDE_DIR}tinystr.cpp" + "${TINYXML_INCLUDE_DIR}tinyxml.cpp" + "${TINYXML_INCLUDE_DIR}tinyxmlerror.cpp" + "${TINYXML_INCLUDE_DIR}tinyxmlparser.cpp") +endif() set(CPPCHECK_LIB_DIR "${CPPCHECK_SOURCE_DIR}/lib/") include("${CPPCHECK_LIB_DIR}library_sources.cmake") @@ -37,7 +42,5 @@ if (CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wshadow -Wno-long-long -Wfloat-equal -Wcast-qual") endif (CMAKE_COMPILER_IS_GNUCXX) -include_directories("${CPPCHECK_SOURCE_DIR}/lib" - "${TINYXML_INCLUDE_DIR}") add_executable(cppcheck ${CHECKCLI_SRCS} ${CPPCHECK_LIB_SOURCES}) TARGET_LINK_LIBRARIES(cppcheck ${CHECK_LIBS}) From cb473a48b7afda9f00606d55d57c6986675b8eb2 Mon Sep 17 00:00:00 2001 From: Daniel Marjamaki Date: Wed, 6 Apr 2011 19:49:04 +0200 Subject: [PATCH 2/9] Preprocessor: Use Settings::debugwarnings instead of NDEBUG to determine if 'missing system include' should be reported or not --- lib/preprocessor.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 227733e95..bfc68a027 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1910,13 +1910,7 @@ void Preprocessor::handleIncludes(std::string &code, const std::string &filePath } else if (!fileOpened) { - // TODO: Fix the handling of system includes and then - // remove the "headerType == UserHeader" -#ifdef NDEBUG - if (headerType == UserHeader && _errorLogger && _settings && _settings->isEnabled("missingInclude")) -#else - if (_errorLogger && _settings && _settings->isEnabled("missingInclude")) -#endif + if (_errorLogger && _settings && ((headerType == UserHeader) && _settings->isEnabled("missingInclude") || _settings->debugwarnings)) { std::string f = filePath; From 1907590303a7e67c73c94bf092d7f19c12ec3dfc Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Wed, 6 Apr 2011 21:34:11 +0300 Subject: [PATCH 3/9] Installer: Add Spanish translation file. --- win_installer/cppcheck.wxs | 1 + 1 file changed, 1 insertion(+) diff --git a/win_installer/cppcheck.wxs b/win_installer/cppcheck.wxs index 47440dd51..ed4e5098c 100644 --- a/win_installer/cppcheck.wxs +++ b/win_installer/cppcheck.wxs @@ -42,6 +42,7 @@ + From b5bdb9eeaecf44d7abdaeb2a2e910f6728cb65bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 6 Apr 2011 21:40:50 +0200 Subject: [PATCH 4/9] fixed gcc compiler warning --- lib/preprocessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index bfc68a027..7ebc742ff 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1910,7 +1910,7 @@ void Preprocessor::handleIncludes(std::string &code, const std::string &filePath } else if (!fileOpened) { - if (_errorLogger && _settings && ((headerType == UserHeader) && _settings->isEnabled("missingInclude") || _settings->debugwarnings)) + if (_errorLogger && _settings && ((headerType == UserHeader && _settings->isEnabled("missingInclude")) || _settings->debugwarnings)) { std::string f = filePath; From 8482eb9d5c38676a3b4ae899e67b9370eb700cb5 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Thu, 7 Apr 2011 00:33:54 +0200 Subject: [PATCH 5/9] Obsolete functions: Fix messages for gethostbyaddr, gethostbyname --- lib/checkobsoletefunctions.h | 4 ++-- test/testobsoletefunctions.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/checkobsoletefunctions.h b/lib/checkobsoletefunctions.h index 3c56516e2..1fd705b74 100644 --- a/lib/checkobsoletefunctions.h +++ b/lib/checkobsoletefunctions.h @@ -68,8 +68,8 @@ private: { _obsoleteFunctions.push_back(std::make_pair("bsd_signal","Found obsolete function 'bsd_signal'. It is recommended that new applications use the 'sigaction' function")); - _obsoleteFunctions.push_back(std::make_pair("gethostbyaddr","Found obsolete function 'gethostbyaddr'. It is recommended that new applications use the 'getaddrinfo' function")); - _obsoleteFunctions.push_back(std::make_pair("gethostbyname","Found obsolete function 'gethostbyname'. It is recommended that new applications use the 'getnameinfo' function")); + _obsoleteFunctions.push_back(std::make_pair("gethostbyaddr","Found obsolete function 'gethostbyaddr'. It is recommended that new applications use the 'getnameinfo' function")); + _obsoleteFunctions.push_back(std::make_pair("gethostbyname","Found obsolete function 'gethostbyname'. It is recommended that new applications use the 'getaddrinfo' function")); _obsoleteFunctions.push_back(std::make_pair("usleep","Found obsolete function 'usleep'. It is recommended that new applications use the 'nanosleep' or 'setitimer' function\n" "Found obsolete function 'usleep'. POSIX.1-2001 declares usleep() function obsolete and POSIX.1-2008 removes it. It is recommended that new applications use the 'nanosleep' or 'setitimer' function.")); diff --git a/test/testobsoletefunctions.cpp b/test/testobsoletefunctions.cpp index a489191f0..72d24908b 100644 --- a/test/testobsoletefunctions.cpp +++ b/test/testobsoletefunctions.cpp @@ -103,7 +103,7 @@ private: " exit(1);\n" " }\n" "}\n"); - ASSERT_EQUALS("[test.cpp:4]: (style) Found obsolete function 'gethostbyname'. It is recommended that new applications use the 'getnameinfo' function\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (style) Found obsolete function 'gethostbyname'. It is recommended that new applications use the 'getaddrinfo' function\n", errout.str()); } void testgethostbyaddr() @@ -116,7 +116,7 @@ private: " exit(1);\n" " }\n" "}\n"); - ASSERT_EQUALS("[test.cpp:5]: (style) Found obsolete function 'gethostbyaddr'. It is recommended that new applications use the 'getaddrinfo' function\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5]: (style) Found obsolete function 'gethostbyaddr'. It is recommended that new applications use the 'getnameinfo' function\n", errout.str()); } void testusleep() From 803203a876437d0cf0c15705a9764de1b10b590f Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 7 Apr 2011 13:56:45 +0300 Subject: [PATCH 6/9] Fix test VS2008 project file attributes. --- test/test.vcproj | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 test/test.vcproj diff --git a/test/test.vcproj b/test/test.vcproj old mode 100755 new mode 100644 From a5c12172f9d5c01850e5d05cdfbc9ceee894559a Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 7 Apr 2011 15:34:15 +0300 Subject: [PATCH 7/9] GUI: Allow giving project file to command line. GUI now recognizes -p command line parameter. When given (with path to valid project file) GUI automatically loads the project file and starts checking paths in it. Ticket: #2613 (GUI: Should accept project file from command line) --- gui/mainwindow.cpp | 73 +++++++++++++++++++++++++++++----------------- gui/mainwindow.h | 12 ++++++++ 2 files changed, 58 insertions(+), 27 deletions(-) diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 4281166c7..efa99910b 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -117,7 +117,7 @@ MainWindow::MainWindow() : args.removeFirst(); if (!args.isEmpty()) { - DoCheckFiles(args); + HandleCLIParams(args); } } @@ -127,6 +127,21 @@ MainWindow::~MainWindow() delete mProject; } +void MainWindow::HandleCLIParams(const QStringList ¶ms) +{ + if (params.contains("-p")) + { + QString projFile; + const int ind = params.indexOf("-p"); + if ((ind + 1) < params.length()) + projFile = params[ind + 1]; + + LoadProjectFile(projFile); + } + else + DoCheckFiles(params); +} + void MainWindow::LoadSettings() { if (mSettings->value(SETTINGS_WINDOW_MAXIMIZED, false).toBool()) @@ -730,39 +745,43 @@ void MainWindow::OpenProjectFile() if (!filepath.isEmpty()) { - QFileInfo inf(filepath); - const QString filename = inf.fileName(); - FormatAndSetTitle(tr("Project: ") + QString(" ") + filename); + LoadProjectFile(filepath); + } +} - mUI.mActionCloseProjectFile->setEnabled(true); - mUI.mActionEditProjectFile->setEnabled(true); - delete mProject; - mProject = new Project(filepath, this); - mProject->Open(); - QString rootpath = mProject->GetProjectFile()->GetRootPath(); +void MainWindow::LoadProjectFile(const QString &filePath) +{ + QFileInfo inf(filePath); + const QString filename = inf.fileName(); + FormatAndSetTitle(tr("Project: ") + QString(" ") + filename); - // If root path not give or "current dir" then use project file's directory - // as check path - if (rootpath.isEmpty() || rootpath == ".") - mCurrentDirectory = inf.canonicalPath(); - else - mCurrentDirectory = rootpath; + mUI.mActionCloseProjectFile->setEnabled(true); + mUI.mActionEditProjectFile->setEnabled(true); + delete mProject; + mProject = new Project(filePath, this); + mProject->Open(); + QString rootpath = mProject->GetProjectFile()->GetRootPath(); - QStringList paths = mProject->GetProjectFile()->GetCheckPaths(); - if (!paths.isEmpty()) + // If root path not give or "current dir" then use project file's directory + // as check path + if (rootpath.isEmpty() || rootpath == ".") + mCurrentDirectory = inf.canonicalPath(); + else + mCurrentDirectory = rootpath; + + QStringList paths = mProject->GetProjectFile()->GetCheckPaths(); + if (!paths.isEmpty()) + { + for (int i = 0; i < paths.size(); i++) { - for (int i = 0; i < paths.size(); i++) + if (!QDir::isAbsolutePath(paths[i])) { - if (!QDir::isAbsolutePath(paths[i])) - { - QString path = mCurrentDirectory + "/"; - path += paths[i]; - paths[i] = QDir::cleanPath(path); - } + QString path = mCurrentDirectory + "/"; + path += paths[i]; + paths[i] = QDir::cleanPath(path); } - - DoCheckFiles(paths); } + DoCheckFiles(paths); } } diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 04cefede7..c316f5970 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -360,6 +360,18 @@ protected: */ void AddIncludeDirs(const QStringList &includeDirs, Settings &result); + /** + * @brief Handle command line parameters given to GUI. + * @param params List of string given to command line. + */ + void HandleCLIParams(const QStringList ¶ms); + + /** + * @brief Load project file to the GUI. + * @param filePath Filename (inc. path) of project file to load. + */ + void LoadProjectFile(const QString &filePath); + /** * @brief Program settings * From 1752cb62dc0bb8d7289745eb01abb6103089ed74 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 7 Apr 2011 16:07:55 +0300 Subject: [PATCH 8/9] GUI: Print command line help with -h and --help. --- gui/main.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/gui/main.cpp b/gui/main.cpp index fbc709744..30dcc246b 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -21,12 +21,21 @@ #include #include #include +#include +#include #include "mainwindow.h" #include "erroritem.h" +void ShowUsage(); +bool CheckArgs(const QStringList &args); + int main(int argc, char *argv[]) { QApplication app(argc, argv); + + if (!CheckArgs(app.arguments())) + return 0; + app.setWindowIcon(QIcon(":icon.png")); // Register this metatype that is used to transfer error info @@ -40,3 +49,25 @@ int main(int argc, char *argv[]) window.show(); return app.exec(); } + +// Check only arguments needing action before GUI is shown. +// Rest of the arguments are handled in MainWindow::HandleCLIParams() +bool CheckArgs(const QStringList &args) +{ + if (args.contains("-h") || args.contains("--help")) + { + ShowUsage(); + return false; + } + return true; +} + +void ShowUsage() +{ + std::cout << "Cppcheck GUI.\n\n"; + std::cout << "Syntax:\n"; + std::cout << " cppcheck-gui [OPTIONS] [files or paths]\n\n"; + std::cout << "Options:\n"; + std::cout << " -h, --help Print this help\n"; + std::cout << " -p Open given project file and start checking it\n"; +} From fbc8223a6b32935e2001d688756600829baaec10 Mon Sep 17 00:00:00 2001 From: Daniel Marjamaki Date: Thu, 7 Apr 2011 16:53:42 +0200 Subject: [PATCH 9/9] Preprocessor: Fixed expandMacros problem. Ticket: #2707 --- lib/preprocessor.cpp | 17 ++++++++++------- test/testpreprocessor.cpp | 13 +++++++++++-- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 7ebc742ff..a648e76ea 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -2378,14 +2378,17 @@ public: } // expand nopar macro - const std::map::const_iterator it = macros.find(str); - if (it != macros.end() && it->second->_macro.find("(") == std::string::npos) + if (tok->strAt(-1) != "##") { - str = it->second->_macro; - if (str.find(" ") != std::string::npos) - str.erase(0, str.find(" ")); - else - str = ""; + const std::map::const_iterator it = macros.find(str); + if (it != macros.end() && it->second->_macro.find("(") == std::string::npos) + { + str = it->second->_macro; + if (str.find(" ") != std::string::npos) + str.erase(0, str.find(" ")); + else + str = ""; + } } } if (_variadic && tok->str() == "," && tok->next() && tok->next()->str() == "##") diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 96e1a33cf..aa341688f 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -159,7 +159,8 @@ private: TEST_CASE(macro_simple13); TEST_CASE(macro_simple14); TEST_CASE(macro_simple15); - TEST_CASE(macroInMacro); + TEST_CASE(macroInMacro1); + TEST_CASE(macroInMacro2); TEST_CASE(macro_mismatch); TEST_CASE(macro_linenumbers); TEST_CASE(macro_nopar); @@ -1692,7 +1693,7 @@ private: ASSERT_EQUALS("\n\"foo\"\n", OurPreprocessor::expandMacros(filedata)); } - void macroInMacro() + void macroInMacro1() { { const char filedata[] = "#define A(m) long n = m; n++;\n" @@ -1793,6 +1794,14 @@ private: } } + void macroInMacro2() + { + const char filedata[] = "#define A(x) a##x\n" + "#define B 0\n" + "A(B)\n"; + ASSERT_EQUALS("\n\naB\n", OurPreprocessor::expandMacros(filedata)); + } + void macro_mismatch() { const char filedata[] = "#define AAA(aa,bb) f(aa)\n"