diff --git a/Makefile b/Makefile
index 794e7c5d1..ea8a3a46e 100644
--- a/Makefile
+++ b/Makefile
@@ -92,12 +92,16 @@ TESTOBJ = test/options.o \
test/testunusedprivfunc.o \
test/testunusedvar.o
-EXTOBJ = externals/tinyxml/tinystr.o \
+#ifndef TINYXML
+ TINYXML = externals/tinyxml/tinystr.o \
externals/tinyxml/tinyxml.o \
externals/tinyxml/tinyxmlerror.o \
externals/tinyxml/tinyxmlparser.o
+#endif
+EXTOBJ += $(TINYXML)
+
###### Targets
cppcheck: $(LIBOBJ) $(CLIOBJ) $(EXTOBJ)
diff --git a/gui/test/main.cpp b/gui/test/main.cpp
new file mode 100644
index 000000000..fc17d81f0
--- /dev/null
+++ b/gui/test/main.cpp
@@ -0,0 +1,35 @@
+/*
+ * Cppcheck - A tool for static C/C++ code analysis
+ * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include "testtranslationhandler.h"
+#include "testxmlreport.h"
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication a(argc, argv);
+
+ TestTranslationHandler testTtranslationHandler;
+ QTest::qExec(&testTtranslationHandler);
+
+ TestXmlReport testXmlReport;
+ QTest::qExec(&testXmlReport);
+
+ return a.exec();
+}
diff --git a/gui/test/test.pro b/gui/test/test.pro
new file mode 100644
index 000000000..892ded31d
--- /dev/null
+++ b/gui/test/test.pro
@@ -0,0 +1,22 @@
+TEMPLATE = app
+TARGET = test
+CONFIG += qtestlib
+DEPENDPATH += . ..
+INCLUDEPATH += . ..
+
+# tests
+SOURCES += main.cpp \
+ testtranslationhandler.cpp \
+ testxmlreport.cpp
+
+HEADERS += testtranslationhandler.h \
+ testxmlreport.h
+
+# GUI
+SOURCES += report.cpp \
+ ../translationhandler.cpp \
+ ../xmlreport.cpp
+
+HEADERS += report.h \
+ ../translationhandler.h \
+ ../xmlreport.h
diff --git a/gui/test/testtranslationhandler.cpp b/gui/test/testtranslationhandler.cpp
new file mode 100644
index 000000000..dc0b17f3d
--- /dev/null
+++ b/gui/test/testtranslationhandler.cpp
@@ -0,0 +1,29 @@
+/*
+ * Cppcheck - A tool for static C/C++ code analysis
+ * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include "testtranslationhandler.h"
+#include "translationhandler.h"
+
+void TestTranslationHandler::construct()
+{
+ TranslationHandler handler;
+ QCOMPARE(10, handler.GetNames().size());
+ QCOMPARE(QString("en"), handler.GetCurrentLanguage());
+}
diff --git a/gui/test/testtranslationhandler.h b/gui/test/testtranslationhandler.h
new file mode 100644
index 000000000..6f4235889
--- /dev/null
+++ b/gui/test/testtranslationhandler.h
@@ -0,0 +1,28 @@
+/*
+ * Cppcheck - A tool for static C/C++ code analysis
+ * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+
+class TestTranslationHandler: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void construct();
+};
diff --git a/gui/test/testxmlreport.cpp b/gui/test/testxmlreport.cpp
new file mode 100644
index 000000000..291b07065
--- /dev/null
+++ b/gui/test/testxmlreport.cpp
@@ -0,0 +1,37 @@
+/*
+ * Cppcheck - A tool for static C/C++ code analysis
+ * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include "testxmlreport.h"
+#include "xmlreport.h"
+
+void TestXmlReport::testQuoteMessage()
+{
+ const QString toQuote("abcdefgh&\"'<>12345");
+ const QString quoted("abcdefgh&"'<>12345");
+ QCOMPARE(quoted, XmlReport::quoteMessage(toQuote));
+}
+
+void TestXmlReport::testUnquoteMessage()
+{
+ const QString toQuote("abcdefgh&\"'<>12345");
+ const QString quoted("abcdefgh&"'<>12345");
+ QCOMPARE(toQuote, XmlReport::unquoteMessage(quoted));
+}
+
diff --git a/gui/test/testxmlreport.h b/gui/test/testxmlreport.h
new file mode 100644
index 000000000..2304c5252
--- /dev/null
+++ b/gui/test/testxmlreport.h
@@ -0,0 +1,29 @@
+/*
+ * Cppcheck - A tool for static C/C++ code analysis
+ * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+
+class TestXmlReport: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void testQuoteMessage();
+ void testUnquoteMessage();
+};
diff --git a/gui/translationhandler.h b/gui/translationhandler.h
index 8640b7ea3..2d396c579 100644
--- a/gui/translationhandler.h
+++ b/gui/translationhandler.h
@@ -63,7 +63,7 @@ class TranslationHandler : QObject
{
Q_OBJECT
public:
- TranslationHandler(QObject *parent);
+ TranslationHandler(QObject *parent = 0);
virtual ~TranslationHandler();
/**
diff --git a/lib/checkother.cpp b/lib/checkother.cpp
index 891502d6e..1e94d1b33 100644
--- a/lib/checkother.cpp
+++ b/lib/checkother.cpp
@@ -1912,8 +1912,6 @@ void CheckOther::functionVariableUsage()
variables.use(tok->next()->varId()); // use = read + write
else if (Token::Match(tok, "[;{}] %var% >>"))
variables.use(tok->next()->varId()); // use = read + write
- else if (Token::Match(tok, "[{,] %var% [,}]"))
- variables.read(tok->next()->varId());
// function parameter
else if (Token::Match(tok, "[(,] %var% ["))
@@ -1932,6 +1930,9 @@ void CheckOther::functionVariableUsage()
variables.read(tok->tokAt(2)->varId());
}
+ else if (Token::Match(tok, "[{,] %var% [,}]"))
+ variables.read(tok->next()->varId());
+
else if (Token::Match(tok, "%var% ."))
variables.use(tok->varId()); // use = read + write
diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp
index b74eb6793..37c6281a9 100644
--- a/lib/tokenize.cpp
+++ b/lib/tokenize.cpp
@@ -209,7 +209,7 @@ unsigned int Tokenizer::sizeOfType(const Token *type) const
if (type->str()[0] == '"')
return static_cast(Token::getStrLength(type) + 1);
- std::map::const_iterator it = _typeSize.find(type->strAt(0));
+ std::map::const_iterator it = _typeSize.find(type->str());
if (it == _typeSize.end())
return 0;
else if (type->isLong())
@@ -804,7 +804,7 @@ static Token *splitDefinitionFromTypedef(Token *tok)
tok1->insertToken("const");
tok1 = tok1->next();
}
- tok1->insertToken(tok->next()->strAt(0)); // struct, union or enum
+ tok1->insertToken(tok->next()->str()); // struct, union or enum
tok1 = tok1->next();
tok1->insertToken(name.c_str());
tok->deleteThis();
@@ -1382,13 +1382,14 @@ void Tokenizer::simplifyTypedef()
bool inCast = false;
bool inTemplate = false;
bool inOperator = false;
+ bool inSizeof = false;
// check for derived class: class A : some_typedef {
isDerived = Token::Match(tok2->previous(), "public|protected|private %type% {|,");
// check for cast: (some_typedef) A or static_cast(A)
// todo: check for more complicated casts like: (const some_typedef *)A
- if ((tok2->previous()->str() == "(" && tok2->next()->str() == ")") ||
+ if ((tok2->previous()->str() == "(" && tok2->next()->str() == ")" && tok2->strAt(-2) != "sizeof") ||
(tok2->previous()->str() == "<" && Token::simpleMatch(tok2->next(), "> (")))
inCast = true;
@@ -1397,6 +1398,9 @@ void Tokenizer::simplifyTypedef()
Token::Match(tok2->next(), "&|*| &|*| >|,"))
inTemplate = true;
+ else if (Token::Match(tok2->tokAt(-2), "sizeof ( %type% )"))
+ inSizeof = true;
+
// check for operator
if (Token::simpleMatch(tok2->previous(), "operator") ||
Token::simpleMatch(tok2->tokAt(-2), "operator const"))
@@ -1447,7 +1451,7 @@ void Tokenizer::simplifyTypedef()
Token *nextTok;
for (nextTok = funcStart; nextTok != funcEnd->next(); nextTok = nextTok->next())
{
- tok2->insertToken(nextTok->strAt(0));
+ tok2->insertToken(nextTok->str());
tok2 = tok2->next();
// Check for links and fix them up
@@ -1518,7 +1522,7 @@ void Tokenizer::simplifyTypedef()
tok3 = tok2;
for (nextTok = argStart->next(); nextTok != argEnd; nextTok = nextTok->next())
{
- tok2->insertToken(nextTok->strAt(0));
+ tok2->insertToken(nextTok->str());
tok2 = tok2->next();
// Check for links and fix them up
@@ -1655,7 +1659,7 @@ void Tokenizer::simplifyTypedef()
std::stack argLinks;
for (nextArgTok = argStart->next(); nextArgTok != argEnd; nextArgTok = nextArgTok->next())
{
- tok2->insertToken(nextArgTok->strAt(0));
+ tok2->insertToken(nextArgTok->str());
tok2 = tok2->next();
// Check for links and fix them up
@@ -1860,7 +1864,7 @@ void Tokenizer::simplifyTypedef()
std::stack argLinks;
for (nextArgTok = argStart->next(); nextArgTok != argEnd; nextArgTok = nextArgTok->next())
{
- tok2->insertToken(nextArgTok->strAt(0));
+ tok2->insertToken(nextArgTok->str());
tok2 = tok2->next();
// Check for links and fix them up
@@ -1891,12 +1895,13 @@ void Tokenizer::simplifyTypedef()
{
do
{
- tok2 = tok2->next();
+ if (!inCast && !inSizeof)
+ tok2 = tok2->next();
Token * nextArrTok;
std::stack arrLinks;
for (nextArrTok = arrayStart; nextArrTok != arrayEnd->next(); nextArrTok = nextArrTok->next())
{
- tok2->insertToken(nextArrTok->strAt(0));
+ tok2->insertToken(nextArrTok->str());
tok2 = tok2->next();
// Check for links and fix them up
@@ -4059,6 +4064,13 @@ void Tokenizer::simplifySizeof()
sz = sizeOfType(decltok->tokAt(-2));
}
}
+ else if (tok->strAt(3) == "[" && tok->tokAt(2)->isStandardType())
+ {
+ sz = sizeOfType(tok->tokAt(2));
+ if (sz == 0)
+ continue;
+ sz = sz * static_cast(MathLib::toLongNumber(tok->strAt(4)));
+ }
if (sz > 0)
{
@@ -5889,7 +5901,7 @@ void Tokenizer::simplifyIfAssign()
for (tok2 = tok2->next(); tok2 && tok2 != tok; tok2 = tok2->previous())
{
- tok3->insertToken(tok2->strAt(0));
+ tok3->insertToken(tok2->str());
Token *newTok = tok3->next();
newTok->fileIndex(tok2->fileIndex());
@@ -7837,11 +7849,11 @@ void Tokenizer::simplifyEnum()
if (simplify)
{
if (enumValue)
- tok2->str(enumValue->strAt(0));
+ tok2->str(enumValue->str());
else
{
std::stack links;
- tok2->str(enumValueStart->strAt(0));
+ tok2->str(enumValueStart->str());
if (tok2->str() == "(" || tok2->str() == "[" || tok2->str() == "{")
links.push(tok2);
Token * nextToken = enumValueStart->next();
diff --git a/readme.txt b/readme.txt
index bb5e677c3..170559978 100644
--- a/readme.txt
+++ b/readme.txt
@@ -45,8 +45,7 @@ Compiling
g++ (for experts)
=================
If you just want to build Cppcheck then you can use this command:
- g++ -o cppcheck -Ilib cli/*.cpp lib/*.cpp
-
+ g++ -o cppcheck -lpcre -Ilib -Iexternals cli/*.cpp lib/*.cpp externals/tinyxml/*.cpp
mingw
=====
make LDFLAGS=-lshlwapi
diff --git a/runastyle b/runastyle
index 00f2807cb..4da7b7866 100755
--- a/runastyle
+++ b/runastyle
@@ -1,12 +1,14 @@
#!/bin/bash
-style="--style=ansi --min-conditional-indent=0"
+style="--style=ansi --lineend=linux --min-conditional-indent=0"
options="--pad-header --unpad-paren --suffix=none"
astyle $style $options cli/*.cpp
astyle $style $options cli/*.h
astyle $style $options gui/*.cpp
astyle $style $options gui/*.h
+astyle $style $options gui/test/*.cpp
+astyle $style $options gui/test/*.h
astyle $style $options lib/*.cpp
astyle $style $options lib/*.h
astyle $style $options test/*.cpp
diff --git a/runastyle.bat b/runastyle.bat
index 3f3c46527..bf7b73202 100644
--- a/runastyle.bat
+++ b/runastyle.bat
@@ -1,12 +1,14 @@
REM A script to run Astyle for the sources
-SET STYLE=--style=ansi --min-conditional-indent=0
+SET STYLE=--style=ansi --lineend=linux --min-conditional-indent=0
SET OPTIONS=--pad-header --unpad-paren --suffix=none
astyle %STYLE% %OPTIONS% cli/*.cpp
astyle %STYLE% %OPTIONS% cli/*.h
astyle %STYLE% %OPTIONS% gui/*.cpp
astyle %STYLE% %OPTIONS% gui/*.h
+astyle %STYLE% %OPTIONS% gui/test/*.cpp
+astyle %STYLE% %OPTIONS% gui/test/*.h
astyle %STYLE% %OPTIONS% lib/*.cpp
astyle %STYLE% %OPTIONS% lib/*.h
astyle %STYLE% %OPTIONS% test/*.cpp
diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp
index 0de4ff250..fe8d2b8a9 100644
--- a/test/testsimplifytokens.cpp
+++ b/test/testsimplifytokens.cpp
@@ -234,6 +234,7 @@ private:
TEST_CASE(simplifyTypedef74); // ticket #2414
TEST_CASE(simplifyTypedef75); // ticket #2426
TEST_CASE(simplifyTypedef76); // ticket #2453
+ TEST_CASE(simplifyTypedef77); // ticket #2554
TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@@ -4838,6 +4839,13 @@ private:
ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str());
}
+ void simplifyTypedef77() // ticket #2554
+ {
+ const char code[] = "typedef char Str[10]; int x = sizeof(Str);\n";
+ const std::string expected = "; int x ; x = 10 ;";
+ ASSERT_EQUALS(expected, sizeof_(code));
+ }
+
void simplifyTypedefFunction1()
{
{
diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp
index a417ccf5f..c782364f2 100644
--- a/test/testunusedvar.cpp
+++ b/test/testunusedvar.cpp
@@ -82,6 +82,7 @@ private:
TEST_CASE(localvar32); // ticket #2330
TEST_CASE(localvar33); // ticket #2346
TEST_CASE(localvar34); // ticket #2368
+ TEST_CASE(localvar35); // ticket #2535
TEST_CASE(localvaralias1);
TEST_CASE(localvaralias2); // ticket #1637
TEST_CASE(localvaralias3); // ticket #1639
@@ -1372,6 +1373,15 @@ private:
ASSERT_EQUALS("", errout.str());
}
+ void localvar35() // ticket #2535
+ {
+ functionVariableUsage("void f() {\n"
+ " int a, b;\n"
+ " x(1,a,b);\n"
+ "}\n");
+ ASSERT_EQUALS("", errout.str());
+ }
+
void localvaralias1()
{
functionVariableUsage("void foo()\n"
diff --git a/tools/dmake.cpp b/tools/dmake.cpp
index 7e688f33c..572e389eb 100644
--- a/tools/dmake.cpp
+++ b/tools/dmake.cpp
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#if defined(_WIN32)
#include "../cli/fileLister_win32.h"
@@ -107,6 +108,52 @@ static void makeConditionalVariable(std::ostream &os, const std::string &variabl
<< "\n";
}
+static std::string getLibName(const std::string &path)
+{
+ // path can be e.g. "externals/foo/foo.cpp" then returned
+ // library name is "FOO".
+ std::string libName = path.substr(path.find('/')+1);
+ libName = libName.substr(0, libName.find('/'));
+ std::transform(libName.begin(), libName.end(),libName.begin(), ::toupper);
+ return libName;
+}
+
+static void makeExtObj(std::ostream &fout, const std::vector &externalfiles)
+{
+ bool start = true;
+ std::ostringstream libNames;
+ std::string libName;
+ for (unsigned int i = 0; i < externalfiles.size(); ++i)
+ {
+ if (start)
+ {
+ libName = getLibName(externalfiles[i]);
+ fout << "#ifndef " << libName << std::endl;
+ fout << " " << libName << " = " << objfile(externalfiles[i]);
+ libNames << "EXTOBJ += $(" << libName << ")" << std::endl;
+ start = false;
+ }
+ else
+ {
+ fout << std::string(14, ' ') << objfile(externalfiles[i]);
+ }
+
+ if (i+1 >= externalfiles.size() || libName != getLibName(externalfiles[i+1]))
+ {
+ // This was the last file for this library
+ fout << std::endl << "#endif" << std::endl;
+ fout << "\n\n";
+ start = true;
+ }
+ else
+ {
+ // There are more files for this library
+ fout << " \\" << std::endl;
+ }
+ }
+
+ fout << libNames.str();
+}
int main(int argc, char **argv)
{
@@ -220,11 +267,8 @@ int main(int argc, char **argv)
for (unsigned int i = 1; i < testfiles.size(); ++i)
fout << " \\" << std::endl << std::string(14, ' ') << objfile(testfiles[i]);
fout << "\n\n";
- fout << "EXTOBJ = " << objfile(externalfiles[0]);
- for (unsigned int i = 1; i < externalfiles.size(); ++i)
- fout << " \\" << std::endl << std::string(14, ' ') << objfile(externalfiles[i]);
- fout << "\n\n";
+ makeExtObj(fout, externalfiles);
fout << "\n###### Targets\n\n";
fout << "cppcheck: $(LIBOBJ) $(CLIOBJ) $(EXTOBJ)\n";