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:
parent
3c0619cba5
commit
19a8cfd960
2
Makefile
2
Makefile
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -269,6 +269,7 @@ public:
|
|||
}
|
||||
|
||||
std::set<std::string> returnuninitdata;
|
||||
std::vector<std::string> defines; // to provide some library defines
|
||||
|
||||
private:
|
||||
class ExportedFunctions {
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue