Library: add new "define" tag

This tag will allow to add some preprocessor defs into library.
It would be useful to provide more information about libraries
implementation details. As example GLib's library include tag
was added that helps to detect more memory leaks.
This commit is contained in:
Pavel Roschin 2014-02-06 12:22:07 +04:00
parent 3c0619cba5
commit 19a8cfd960
6 changed files with 82 additions and 1 deletions

View File

@ -452,7 +452,7 @@ test/testlibrary.o: test/testlibrary.cpp lib/library.h lib/config.h lib/path.h l
test/testmathlib.o: test/testmathlib.cpp lib/mathlib.h lib/config.h test/testsuite.h lib/errorlogger.h lib/suppressions.h test/redirect.h lib/library.h lib/path.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) -std=c++0x -c -o test/testmathlib.o test/testmathlib.cpp
test/testmemleak.o: test/testmemleak.cpp lib/tokenize.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/tokenlist.h lib/checkmemoryleak.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/settings.h lib/library.h lib/path.h lib/standards.h lib/timer.h test/testsuite.h test/redirect.h lib/symboldatabase.h
test/testmemleak.o: test/testmemleak.cpp lib/tokenize.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/tokenlist.h lib/checkmemoryleak.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/settings.h lib/library.h lib/path.h lib/standards.h lib/timer.h test/testsuite.h test/redirect.h lib/symboldatabase.h lib/preprocessor.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) -std=c++0x -c -o test/testmemleak.o test/testmemleak.cpp
test/testnonreentrantfunctions.o: test/testnonreentrantfunctions.cpp lib/tokenize.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/tokenlist.h lib/checknonreentrantfunctions.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/settings.h lib/library.h lib/path.h lib/standards.h lib/timer.h test/testsuite.h test/redirect.h

View File

@ -1,6 +1,10 @@
<?xml version="1.0"?>
<!-- THIS FILE IS GENERATED AUTOMATICALLY. See https://github.com/scriptum/cppcheck-libs -->
<def>
<define name="g_return_if_fail(expr)" value="do{if(!(expr)){return;}}while(0)"/>
<define name="g_return_val_if_fail(expr, val)" value="do{if(!(expr)){return val;}}while(0)"/>
<define name="g_return_if_reached()" value="do{return;}while(0)"/>
<define name="g_return_val_if_reached(val)" value="do{return val;}while(0)"/>
<memory>
<alloc init="true">g_thread_new</alloc>
<alloc init="true">g_thread_try_new</alloc>

View File

@ -127,6 +127,20 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
}
}
else if (strcmp(node->Name(),"define")==0) {
const char *name = node->Attribute("name");
if (name == NULL)
return false;
const char *value = node->Attribute("value");
if (value == NULL)
return false;
defines.push_back(std::string("#define ") +
name +
" " +
value +
"\n");
}
else if (strcmp(node->Name(),"function")==0) {
const char *name = node->Attribute("name");
if (name == NULL)

View File

@ -269,6 +269,7 @@ public:
}
std::set<std::string> returnuninitdata;
std::vector<std::string> defines; // to provide some library defines
private:
class ExportedFunctions {

View File

@ -994,6 +994,13 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
"#endfile\n"
;
}
for (std::vector<std::string>::iterator it = _settings->library.defines.begin();
it != _settings->library.defines.end();
++it)
{
forcedIncludes += *it;
}
}
if (!forcedIncludes.empty()) {

View File

@ -23,6 +23,7 @@
#include "checkmemoryleak.h"
#include "testsuite.h"
#include "symboldatabase.h"
#include "preprocessor.h"
#include <sstream>
extern std::ostringstream errout;
@ -6273,3 +6274,57 @@ private:
}
};
REGISTER_TEST(TestMemleakNoVar)
class TestMemleakGLib : public TestFixture {
public:
TestMemleakGLib() : TestFixture("TestMemleakGLib") {
}
private:
void check(const char code[]) {
// Clear the error buffer..
errout.str("");
Settings settings;
LOAD_LIB("gtk.cfg");
settings.library = _lib;
// Preprocess...
Preprocessor preprocessor(&settings, this);
std::istringstream istrpreproc(code);
std::map<std::string, std::string> actual;
preprocessor.preprocess(istrpreproc, actual, "test.c");
// Tokenize..
Tokenizer tokenizer(&settings, this);
std::istringstream istr(actual[""]);
tokenizer.tokenize(istr, "test.c");
tokenizer.simplifyTokenList2();
// Check for memory leaks..
CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, &settings, this);
checkMemoryLeak.checkReallocUsage();
checkMemoryLeak.check();
}
void run() {
TEST_CASE(glib1);
}
void glib1() {
check("void f(gchar *_a, gchar *_b) {"
" g_return_if_fail(_a);"
" gchar *a = g_strdup(_a);"
" g_return_if_fail(_b);"
" gchar *b = g_strdup(_b);"
" g_free(a);"
" g_free(b);"
"}");
ASSERT_EQUALS("[test.c:1]: (error) Memory leak: a\n", errout.str());
}
};
static TestMemleakGLib testMemleakGLib;