Merge branch 'master' of git://github.com/danmar/cppcheck

This commit is contained in:
Markus Elfring 2011-04-07 16:55:47 +02:00
commit 0d76d87770
10 changed files with 129 additions and 57 deletions

View File

@ -1,24 +1,29 @@
# Minimal CMake build file to build cppcheck command line executable # Minimal CMake build file to build cppcheck command line executable
include_directories("${CPPCHECK_SOURCE_DIR}/lib")
if(PCRE_FOUND) if(PCRE_FOUND)
add_definitions(-DHAVE_RULES) 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}) set(CHECK_LIBS ${PCRE_LIBRARIES})
endif() endif()
set(TINYXML_INCLUDE_DIR "${CPPCHECK_SOURCE_DIR}/externals/tinyxml/")
SET(CHECKCLI_SRCS SET(CHECKCLI_SRCS
cmdlineparser.cpp cmdlineparser.cpp
cppcheckexecutor.cpp cppcheckexecutor.cpp
filelister.cpp filelister.cpp
main.cpp main.cpp
threadexecutor.cpp
pathmatch.cpp pathmatch.cpp
"${TINYXML_INCLUDE_DIR}tinystr.cpp" threadexecutor.cpp)
"${TINYXML_INCLUDE_DIR}tinyxml.cpp"
"${TINYXML_INCLUDE_DIR}tinyxmlerror.cpp" if(PCRE_FOUND)
"${TINYXML_INCLUDE_DIR}tinyxmlparser.cpp") 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/") set(CPPCHECK_LIB_DIR "${CPPCHECK_SOURCE_DIR}/lib/")
include("${CPPCHECK_LIB_DIR}library_sources.cmake") 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") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wshadow -Wno-long-long -Wfloat-equal -Wcast-qual")
endif (CMAKE_COMPILER_IS_GNUCXX) endif (CMAKE_COMPILER_IS_GNUCXX)
include_directories("${CPPCHECK_SOURCE_DIR}/lib"
"${TINYXML_INCLUDE_DIR}")
add_executable(cppcheck ${CHECKCLI_SRCS} ${CPPCHECK_LIB_SOURCES}) add_executable(cppcheck ${CHECKCLI_SRCS} ${CPPCHECK_LIB_SOURCES})
TARGET_LINK_LIBRARIES(cppcheck ${CHECK_LIBS}) TARGET_LINK_LIBRARIES(cppcheck ${CHECK_LIBS})

View File

@ -21,12 +21,21 @@
#include <QTextCodec> #include <QTextCodec>
#include <QTranslator> #include <QTranslator>
#include <QMetaType> #include <QMetaType>
#include <QStringList>
#include <iostream>
#include "mainwindow.h" #include "mainwindow.h"
#include "erroritem.h" #include "erroritem.h"
void ShowUsage();
bool CheckArgs(const QStringList &args);
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
if (!CheckArgs(app.arguments()))
return 0;
app.setWindowIcon(QIcon(":icon.png")); app.setWindowIcon(QIcon(":icon.png"));
// Register this metatype that is used to transfer error info // Register this metatype that is used to transfer error info
@ -40,3 +49,25 @@ int main(int argc, char *argv[])
window.show(); window.show();
return app.exec(); 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 <file> Open given project file and start checking it\n";
}

View File

@ -117,7 +117,7 @@ MainWindow::MainWindow() :
args.removeFirst(); args.removeFirst();
if (!args.isEmpty()) if (!args.isEmpty())
{ {
DoCheckFiles(args); HandleCLIParams(args);
} }
} }
@ -127,6 +127,21 @@ MainWindow::~MainWindow()
delete mProject; delete mProject;
} }
void MainWindow::HandleCLIParams(const QStringList &params)
{
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() void MainWindow::LoadSettings()
{ {
if (mSettings->value(SETTINGS_WINDOW_MAXIMIZED, false).toBool()) if (mSettings->value(SETTINGS_WINDOW_MAXIMIZED, false).toBool())
@ -730,39 +745,43 @@ void MainWindow::OpenProjectFile()
if (!filepath.isEmpty()) if (!filepath.isEmpty())
{ {
QFileInfo inf(filepath); LoadProjectFile(filepath);
const QString filename = inf.fileName(); }
FormatAndSetTitle(tr("Project: ") + QString(" ") + filename); }
mUI.mActionCloseProjectFile->setEnabled(true); void MainWindow::LoadProjectFile(const QString &filePath)
mUI.mActionEditProjectFile->setEnabled(true); {
delete mProject; QFileInfo inf(filePath);
mProject = new Project(filepath, this); const QString filename = inf.fileName();
mProject->Open(); FormatAndSetTitle(tr("Project: ") + QString(" ") + filename);
QString rootpath = mProject->GetProjectFile()->GetRootPath();
// If root path not give or "current dir" then use project file's directory mUI.mActionCloseProjectFile->setEnabled(true);
// as check path mUI.mActionEditProjectFile->setEnabled(true);
if (rootpath.isEmpty() || rootpath == ".") delete mProject;
mCurrentDirectory = inf.canonicalPath(); mProject = new Project(filePath, this);
else mProject->Open();
mCurrentDirectory = rootpath; QString rootpath = mProject->GetProjectFile()->GetRootPath();
QStringList paths = mProject->GetProjectFile()->GetCheckPaths(); // If root path not give or "current dir" then use project file's directory
if (!paths.isEmpty()) // 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];
QString path = mCurrentDirectory + "/"; paths[i] = QDir::cleanPath(path);
path += paths[i];
paths[i] = QDir::cleanPath(path);
}
} }
DoCheckFiles(paths);
} }
DoCheckFiles(paths);
} }
} }

View File

@ -360,6 +360,18 @@ protected:
*/ */
void AddIncludeDirs(const QStringList &includeDirs, Settings &result); 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 &params);
/**
* @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 * @brief Program settings
* *

View File

@ -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("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("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 '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" _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.")); "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."));

View File

@ -1910,13 +1910,7 @@ void Preprocessor::handleIncludes(std::string &code, const std::string &filePath
} }
else if (!fileOpened) else if (!fileOpened)
{ {
// TODO: Fix the handling of system includes and then if (_errorLogger && _settings && ((headerType == UserHeader && _settings->isEnabled("missingInclude")) || _settings->debugwarnings))
// remove the "headerType == UserHeader"
#ifdef NDEBUG
if (headerType == UserHeader && _errorLogger && _settings && _settings->isEnabled("missingInclude"))
#else
if (_errorLogger && _settings && _settings->isEnabled("missingInclude"))
#endif
{ {
std::string f = filePath; std::string f = filePath;
@ -2384,14 +2378,17 @@ public:
} }
// expand nopar macro // expand nopar macro
const std::map<std::string, PreprocessorMacro *>::const_iterator it = macros.find(str); if (tok->strAt(-1) != "##")
if (it != macros.end() && it->second->_macro.find("(") == std::string::npos)
{ {
str = it->second->_macro; const std::map<std::string, PreprocessorMacro *>::const_iterator it = macros.find(str);
if (str.find(" ") != std::string::npos) if (it != macros.end() && it->second->_macro.find("(") == std::string::npos)
str.erase(0, str.find(" ")); {
else str = it->second->_macro;
str = ""; if (str.find(" ") != std::string::npos)
str.erase(0, str.find(" "));
else
str = "";
}
} }
} }
if (_variadic && tok->str() == "," && tok->next() && tok->next()->str() == "##") if (_variadic && tok->str() == "," && tok->next() && tok->next()->str() == "##")

0
test/test.vcproj Executable file → Normal file
View File

View File

@ -103,7 +103,7 @@ private:
" exit(1);\n" " exit(1);\n"
" }\n" " }\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() void testgethostbyaddr()
@ -116,7 +116,7 @@ private:
" exit(1);\n" " exit(1);\n"
" }\n" " }\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() void testusleep()

View File

@ -159,7 +159,8 @@ private:
TEST_CASE(macro_simple13); TEST_CASE(macro_simple13);
TEST_CASE(macro_simple14); TEST_CASE(macro_simple14);
TEST_CASE(macro_simple15); TEST_CASE(macro_simple15);
TEST_CASE(macroInMacro); TEST_CASE(macroInMacro1);
TEST_CASE(macroInMacro2);
TEST_CASE(macro_mismatch); TEST_CASE(macro_mismatch);
TEST_CASE(macro_linenumbers); TEST_CASE(macro_linenumbers);
TEST_CASE(macro_nopar); TEST_CASE(macro_nopar);
@ -1692,7 +1693,7 @@ private:
ASSERT_EQUALS("\n\"foo\"\n", OurPreprocessor::expandMacros(filedata)); ASSERT_EQUALS("\n\"foo\"\n", OurPreprocessor::expandMacros(filedata));
} }
void macroInMacro() void macroInMacro1()
{ {
{ {
const char filedata[] = "#define A(m) long n = m; n++;\n" 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() void macro_mismatch()
{ {
const char filedata[] = "#define AAA(aa,bb) f(aa)\n" const char filedata[] = "#define AAA(aa,bb) f(aa)\n"

View File

@ -42,6 +42,7 @@
<Component Id='GuiTranslations' Guid='$(var.guiTranslationsGUID)'> <Component Id='GuiTranslations' Guid='$(var.guiTranslationsGUID)'>
<File Id='cppcheck_de.qm' Name='cppcheck_de.qm' Source='$(var.TranslationsDir)\cppcheck_de.qm' /> <File Id='cppcheck_de.qm' Name='cppcheck_de.qm' Source='$(var.TranslationsDir)\cppcheck_de.qm' />
<File Id='cppcheck_en.qm' Name='cppcheck_en.qm' Source='$(var.TranslationsDir)\cppcheck_en.qm' /> <File Id='cppcheck_en.qm' Name='cppcheck_en.qm' Source='$(var.TranslationsDir)\cppcheck_en.qm' />
<File Id='cppcheck_es.qm' Name='cppcheck_es.qm' Source='$(var.TranslationsDir)\cppcheck_es.qm' />
<File Id='cppcheck_fi.qm' Name='cppcheck_fi.qm' Source='$(var.TranslationsDir)\cppcheck_fi.qm' /> <File Id='cppcheck_fi.qm' Name='cppcheck_fi.qm' Source='$(var.TranslationsDir)\cppcheck_fi.qm' />
<File Id='cppcheck_fr.qm' Name='cppcheck_fr.qm' Source='$(var.TranslationsDir)\cppcheck_fr.qm' /> <File Id='cppcheck_fr.qm' Name='cppcheck_fr.qm' Source='$(var.TranslationsDir)\cppcheck_fr.qm' />
<File Id='cppcheck_ja.qm' Name='cppcheck_ja.qm' Source='$(var.TranslationsDir)\cppcheck_ja.qm' /> <File Id='cppcheck_ja.qm' Name='cppcheck_ja.qm' Source='$(var.TranslationsDir)\cppcheck_ja.qm' />