Extended Qt support through Library

This commit is contained in:
Sam Truscott 2013-10-20 14:09:10 +02:00 committed by Daniel Marjamäki
parent fc26de89a9
commit 6806fd8135
13 changed files with 497 additions and 35 deletions

View File

@ -94,7 +94,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
// Execute recursiveAddFiles() to each given file parameter
std::vector<std::string>::const_iterator iter;
for (iter = pathnames.begin(); iter != pathnames.end(); ++iter)
FileLister::recursiveAddFiles(_files, Path::toNativeSeparators(*iter));
FileLister::recursiveAddFiles(_files, Path::toNativeSeparators(*iter), &_settings->library);
}
if (!_files.empty()) {
@ -176,11 +176,25 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
std::size_t processedsize = 0;
unsigned int c = 0;
for (std::map<std::string, std::size_t>::const_iterator i = _files.begin(); i != _files.end(); ++i) {
returnValue += cppCheck.check(i->first);
processedsize += i->second;
if (!settings._errorsOnly)
reportStatus(c + 1, _files.size(), processedsize, totalfilesize);
c++;
if (!_settings->library.acceptFile(i->first)) {
returnValue += cppCheck.check(i->first);
processedsize += i->second;
if (!settings._errorsOnly)
reportStatus(c + 1, _files.size(), processedsize, totalfilesize);
c++;
}
}
// second loop to catch all library files which may not work until all
// c/cpp files have been parsed and checked
for (std::map<std::string, std::size_t>::const_iterator i = _files.begin(); i != _files.end(); ++i) {
if (_settings->library.acceptFile(i->first)) {
returnValue += cppCheck.check(i->first);
processedsize += i->second;
if (!settings._errorsOnly)
reportStatus(c + 1, _files.size(), processedsize, totalfilesize);
c++;
}
}
cppCheck.checkFunctionUsage();

View File

@ -21,6 +21,7 @@
#include <cstring>
#include <string>
#include <sstream>
#include "library.h"
#ifdef _WIN32
@ -67,7 +68,7 @@ static BOOL MyFileExists(const std::string& path)
return result;
}
void FileLister::recursiveAddFiles(std::map<std::string, std::size_t> &files, const std::string &path)
void FileLister::recursiveAddFiles(std::map<std::string, std::size_t> &files, const std::string &path, const Library * library)
{
const std::string cleanedPath = Path::toNativeSeparators(path);
@ -123,7 +124,7 @@ void FileLister::recursiveAddFiles(std::map<std::string, std::size_t> &files, co
// File
const std::string nativename = Path::fromNativeSeparators(fname);
if (!checkAllFilesInDir || Path::acceptFile(fname)) {
if (!checkAllFilesInDir || Path::acceptFile(fname, library)) {
// Limitation: file sizes are assumed to fit in a 'size_t'
#ifdef _WIN64
files[nativename] = (static_cast<std::size_t>(ffd.nFileSizeHigh) << 32) | ffd.nFileSizeLow;
@ -133,7 +134,7 @@ void FileLister::recursiveAddFiles(std::map<std::string, std::size_t> &files, co
}
} else {
// Directory
FileLister::recursiveAddFiles(files, fname);
FileLister::recursiveAddFiles(files, fname, library);
}
} while (FindNextFileA(hFind, &ffd) != FALSE);
@ -187,7 +188,8 @@ std::string FileLister::getAbsolutePath(const std::string& path)
void FileLister::recursiveAddFiles2(std::set<std::string> &seen_paths,
std::map<std::string, std::size_t> &files,
const std::string &path)
const std::string &path,
const Library * library)
{
std::ostringstream oss;
oss << path;
@ -213,7 +215,7 @@ void FileLister::recursiveAddFiles2(std::set<std::string> &seen_paths,
if (filename[filename.length()-1] != '/') {
// File
if (Path::sameFileName(path,filename) || Path::acceptFile(filename)) {
if (Path::sameFileName(path,filename) || Path::acceptFile(filename, library)) {
seen_paths.insert(absolute_path);
struct stat sb;
@ -227,17 +229,17 @@ void FileLister::recursiveAddFiles2(std::set<std::string> &seen_paths,
// Directory
seen_paths.insert(absolute_path);
recursiveAddFiles2(seen_paths, files, filename);
recursiveAddFiles2(seen_paths, files, filename, library);
}
}
globfree(&glob_results);
}
void FileLister::recursiveAddFiles(std::map<std::string, std::size_t> &files, const std::string &path)
void FileLister::recursiveAddFiles(std::map<std::string, std::size_t> &files, const std::string &path, const Library * library)
{
std::set<std::string> seen_paths;
recursiveAddFiles2(seen_paths, files, path);
recursiveAddFiles2(seen_paths, files, path, library);
}
bool FileLister::isDirectory(const std::string &path)

View File

@ -37,7 +37,7 @@ public:
* @param files output map that associates the size of each file with its name
* @param path root path
*/
static void recursiveAddFiles(std::map<std::string, std::size_t> &files, const std::string &path);
static void recursiveAddFiles(std::map<std::string, std::size_t> &files, const std::string &path, const class Library * library);
/**
* @brief Is given path a directory?
@ -56,7 +56,8 @@ public:
static void recursiveAddFiles2(std::set<std::string> &seen_paths,
std::map<std::string, std::size_t> &files,
const std::string &path);
const std::string &path,
const class Library * library);
#endif
};

View File

@ -2016,6 +2016,15 @@ const std::list<const Token *> & CheckClass::callsPureVirtualFunction(const Func
(tok->previous() && tok->previous()->str()=="."))
continue;
if (tok->previous() &&
tok->previous()->str()=="(") {
const Token * prev = tok->previous();
if (prev->previous() &&
(_settings->library.ignorefunction(tok->str())
|| _settings->library.ignorefunction(prev->previous()->str())))
continue;
}
if (isPureWithoutBody(*callFunction)) {
pureFunctionCalls.push_back(tok);
continue;

View File

@ -31,7 +31,7 @@
// FUNCTION USAGE - Check for unused functions etc
//---------------------------------------------------------------------------
void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer)
void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char FileName[], const Settings *settings)
{
// Function declarations..
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
@ -96,6 +96,78 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer)
// Function usage..
const Token *scopeEnd = NULL;
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
// parsing of library code to find called functions
if (settings->library.isexecutableblock(FileName, tok->str())) {
const Token * qmlVarToken = tok->tokAt(settings->library.blockstartoffset(FileName));
int scope = 1;
// find all function calls in library code (starts with '(', not if or while etc)
while (scope) {
if (qmlVarToken->str() == settings->library.blockstart(FileName)) {
scope++;
} else if (qmlVarToken->str() == settings->library.blockend(FileName))
scope--;
else if (qmlVarToken->next()->str() == "(" &&
(!settings->library.iskeyword(FileName, qmlVarToken->str()))) {
if (_functions.find(qmlVarToken->str()) != _functions.end())
_functions[qmlVarToken->str()].usedOtherFile = true;
}
qmlVarToken = qmlVarToken->next();
}
}
if (!settings->library.acceptFile(FileName) // only check c/c++
&& settings->library.isexporter(tok->str()) && tok->next() != 0) {
const Token * qPropToken = tok;
qPropToken = qPropToken->next();
while (qPropToken && qPropToken->str() != ")") {
if (settings->library.isexportedprefix(tok->str(), qPropToken->str())) {
const Token* qNextPropToken = qPropToken->next();
const std::string value = qNextPropToken->str();
if (_functions.find(value) != _functions.end()) {
_functions[value].usedOtherFile = true;
}
}
if (settings->library.isexportedsuffix(tok->str(), qPropToken->str())) {
const Token* qNextPropToken = qPropToken->previous();
const std::string value = qNextPropToken->str();
if (value != ")" && _functions.find(value) != _functions.end()) {
_functions[value].usedOtherFile = true;
}
}
qPropToken = qPropToken->next();
}
}
if (settings->library.acceptFile(FileName)
&& settings->library.isimporter(FileName, tok->str()) && tok->next()) {
const Token * qPropToken = tok;
qPropToken = qPropToken->next();
if (qPropToken->next()) {
qPropToken = qPropToken->next();
while (qPropToken && qPropToken->str() != ")") {
const std::string value = qPropToken->str();
if (!value.empty()) {
_functions[value].usedOtherFile = true;
break;
}
qPropToken = qPropToken->next();
}
}
}
if (settings->library.isreflection(FileName, tok->str())) {
const int index = settings->library.reflectionArgument(FileName, tok->str());
if (index >= 0) {
const Token * funcToken = tok->tokAt(index);
if (funcToken) {
std::string value = funcToken->str();
value = value.substr(1, value.length() - 2);
_functions[value].usedOtherFile = true;
}
}
}
if (scopeEnd == NULL) {
if (!Token::Match(tok, ")|= const| {"))
continue;

View File

@ -44,7 +44,7 @@ public:
// Parse current tokens and determine..
// * Check what functions are used
// * What functions are declared
void parseTokens(const Tokenizer &tokenizer);
void parseTokens(const Tokenizer &tokenizer, const char FileName[], const Settings *settings);
void check(ErrorLogger * const errorLogger);

View File

@ -131,7 +131,7 @@ unsigned int CppCheck::processFile(const std::string& filename, const std::strin
exitcode = 0;
// only show debug warnings for accepted C/C++ source files
if (!Path::acceptFile(filename))
if (!Path::acceptFile(filename, &_settings.library))
_settings.debugwarnings = false;
if (_settings.terminated())
@ -368,7 +368,7 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
}
if (_settings.isEnabled("unusedFunction") && _settings._jobs == 1)
_checkUnusedFunctions.parseTokens(_tokenizer);
_checkUnusedFunctions.parseTokens(_tokenizer, FileName, &_settings);
executeRules("normal", _tokenizer);
@ -557,6 +557,9 @@ void CppCheck::tooManyConfigsError(const std::string &file, const std::size_t nu
void CppCheck::reportErr(const ErrorLogger::ErrorMessage &msg)
{
if (!_settings.library.reportErrors(msg.file0))
return;
std::string errmsg = msg.toString(_settings._verbose);
if (errmsg.empty())
return;

View File

@ -35,7 +35,14 @@ Library::Library(const Library &lib) :
allocid(lib.allocid),
_alloc(lib._alloc),
_dealloc(lib._dealloc),
_noreturn(lib._noreturn)
_noreturn(lib._noreturn),
_ignorefunction(lib._ignorefunction),
_reporterrors(lib._reporterrors),
_fileextensions(lib._fileextensions),
_keywords(lib._keywords),
_executableblocks(lib._executableblocks),
_importers(lib._importers),
_reflection(lib._reflection)
{
}
@ -117,7 +124,7 @@ bool Library::load(const char exename[], const char path[])
_noreturn[name] = (strcmp(functionnode->GetText(), "true") == 0);
else if (strcmp(functionnode->Name(),"leak-ignore")==0)
leakignore.insert(name);
else if (strcmp(functionnode->Name(),"arg")==0 && functionnode->Attribute("nr") != NULL) {
else if (strcmp(functionnode->Name(), "arg") == 0 && functionnode->Attribute("nr") != NULL) {
const int nr = atoi(functionnode->Attribute("nr"));
bool notnull = false;
bool notuninit = false;
@ -139,9 +146,140 @@ bool Library::load(const char exename[], const char path[])
argumentChecks[name][nr].notuninit = notuninit;
argumentChecks[name][nr].formatstr = formatstr;
argumentChecks[name][nr].strz = strz;
} else if (strcmp(functionnode->Name(), "ignorefunction") == 0) {
_ignorefunction[name] = (strcmp(functionnode->GetText(), "true") == 0);
} else
return false;
}
}
else if (strcmp(node->Name(),"files")==0) {
for (const tinyxml2::XMLElement *functionnode = node->FirstChildElement(); functionnode; functionnode = functionnode->NextSiblingElement()) {
if (strcmp(functionnode->Name(), "file") == 0) {
_fileextensions.push_back(functionnode->Attribute("ext"));
const char * report = functionnode->Attribute("reporterrors");
if (report)
_reporterrors[functionnode->Attribute("ext")] = strcmp(report, "true")==0;
} else
return false;
}
}
else if (strcmp(node->Name(), "keywords") == 0) {
for (const tinyxml2::XMLElement *functionnode = node->FirstChildElement(); functionnode; functionnode = functionnode->NextSiblingElement()) {
if (strcmp(functionnode->Name(), "library") == 0) {
const char * const extension = functionnode->Attribute("extension");
if (_keywords.find(extension) == _keywords.end()) {
std::list<std::string> list;
_keywords[extension] = list;
}
for (const tinyxml2::XMLElement *librarynode = functionnode->FirstChildElement(); librarynode; librarynode = librarynode->NextSiblingElement()) {
if (strcmp(librarynode->Name(), "keyword") == 0) {
_keywords.at(extension).push_back(librarynode->Attribute("name"));
} else
return false;
}
} else
return false;
}
}
else if (strcmp(node->Name(), "exported") == 0) {
for (const tinyxml2::XMLElement *functionnode = node->FirstChildElement(); functionnode; functionnode = functionnode->NextSiblingElement()) {
if (strcmp(functionnode->Name(), "exporter") == 0) {
const char * prefix = (functionnode->Attribute("prefix"));
if (prefix) {
std::map<std::string, ExportedFunctions>::const_iterator
it = _exporters.find(prefix);
if (it == _exporters.end()) {
// add the missing list for later on
ExportedFunctions exporter;
_exporters[prefix] = exporter;
}
} else
return false;
for (const tinyxml2::XMLElement *enode = functionnode->FirstChildElement(); enode; enode = enode->NextSiblingElement()) {
if (strcmp(enode->Name(), "prefix") == 0) {
_exporters[prefix].addPrefix(enode->Attribute("name"));
} else if (strcmp(enode->Name(), "suffix") == 0) {
_exporters[prefix].addSuffix(enode->Attribute("name"));
} else
return false;
}
} else
return false;
}
}
else if (strcmp(node->Name(), "imported") == 0) {
for (const tinyxml2::XMLElement *functionnode = node->FirstChildElement(); functionnode; functionnode = functionnode->NextSiblingElement()) {
if (strcmp(functionnode->Name(), "library") == 0) {
const char * const extension = functionnode->Attribute("extension");
if (_importers.find(extension) == _importers.end()) {
std::list<std::string> list;
_importers[extension] = list;
}
for (const tinyxml2::XMLElement *librarynode = functionnode->FirstChildElement(); librarynode; librarynode = librarynode->NextSiblingElement()) {
if (strcmp(librarynode->Name(), "importer") == 0) {
_importers.at(extension).push_back(librarynode->Attribute("name"));
} else
return false;
}
}
}
}
else if (strcmp(node->Name(), "reflection") == 0) {
for (const tinyxml2::XMLElement *functionnode = node->FirstChildElement(); functionnode; functionnode = functionnode->NextSiblingElement()) {
if (strcmp(functionnode->Name(), "library") == 0) {
const char * const extension = functionnode->Attribute("extension");
if (_reflection.find(extension) == _reflection.end()) {
std::map<std::string,int> map;
_reflection[extension] = map;
}
for (const tinyxml2::XMLElement *librarynode = functionnode->FirstChildElement(); librarynode; librarynode = librarynode->NextSiblingElement()) {
if (strcmp(librarynode->Name(), "call") == 0) {
const char * const argString = librarynode->Attribute("arg");
if (argString) {
_reflection.at(extension)[librarynode->Attribute("name")]
= atoi(argString);
}
} else
return false;
}
} else
return false;
}
}
else if (strcmp(node->Name(), "codeblocks") == 0) {
for (const tinyxml2::XMLElement *functionnode = node->FirstChildElement(); functionnode; functionnode = functionnode->NextSiblingElement()) {
if (strcmp(functionnode->Name(), "library") == 0) {
const char * const extension = functionnode->Attribute("extension");
if (_executableblocks.find(extension) == _executableblocks.end()) {
CodeBlock blockInfo;
_executableblocks[extension] = blockInfo;
}
for (const tinyxml2::XMLElement *librarynode = functionnode->FirstChildElement(); librarynode; librarynode = librarynode->NextSiblingElement()) {
if (strcmp(librarynode->Name(), "block") == 0) {
_executableblocks.at(extension).addBlock(librarynode->Attribute("name"));
} else if (strcmp(librarynode->Name(), "structure") == 0) {
const char * start = librarynode->Attribute("start");
if (start)
_executableblocks.at(extension).setStart(start);
const char * end = librarynode->Attribute("end");
if (end)
_executableblocks.at(extension).setEnd(end);
const char * offset = librarynode->Attribute("offset");
if (offset)
_executableblocks.at(extension).setOffset(atoi(offset));
} else
return false;
}
}
}
} else
return false;
}

View File

@ -25,6 +25,10 @@
#include <map>
#include <set>
#include <string>
#include <list>
#include <algorithm>
#include "path.h"
/// @addtogroup Core
/// @{
@ -38,7 +42,7 @@ public:
Library(const Library &);
~Library();
bool load(const char exename[], const char path[]);
bool load(const char exename [], const char path []);
/** get allocation id for function (by name) */
int alloc(const std::string &name) const {
@ -78,12 +82,12 @@ public:
std::set<std::string> leakignore;
bool isnoreturn(const std::string &name) const {
std::map<std::string,bool>::const_iterator it = _noreturn.find(name);
std::map<std::string, bool>::const_iterator it = _noreturn.find(name);
return (it != _noreturn.end() && it->second);
}
bool isnotnoreturn(const std::string &name) const {
std::map<std::string,bool>::const_iterator it = _noreturn.find(name);
std::map<std::string, bool>::const_iterator it = _noreturn.find(name);
return (it != _noreturn.end() && !it->second);
}
@ -102,32 +106,248 @@ public:
std::map<std::string, std::map<int, ArgumentChecks> > argumentChecks;
bool isnullargbad(const std::string &functionName, int argnr) const {
const ArgumentChecks *arg = getarg(functionName,argnr);
const ArgumentChecks *arg = getarg(functionName, argnr);
return arg && arg->notnull;
}
bool isuninitargbad(const std::string &functionName, int argnr) const {
const ArgumentChecks *arg = getarg(functionName,argnr);
const ArgumentChecks *arg = getarg(functionName, argnr);
return arg && arg->notuninit;
}
bool isargformatstr(const std::string &functionName, int argnr) const {
const ArgumentChecks *arg = getarg(functionName,argnr);
const ArgumentChecks *arg = getarg(functionName, argnr);
return arg && arg->formatstr;
}
bool isargstrz(const std::string &functionName, int argnr) const {
const ArgumentChecks *arg = getarg(functionName,argnr);
const ArgumentChecks *arg = getarg(functionName, argnr);
return arg && arg->strz;
}
bool acceptFile(const std::string &path) const {
const std::string extension = Path::getFilenameExtensionInLowerCase(path);
const std::list<std::string>::const_iterator it =
std::find(_fileextensions.begin(), _fileextensions.end(), extension);
return it != _fileextensions.end();
}
bool reportErrors(const std::string &path) const {
const std::map<std::string, bool>::const_iterator it =
_reporterrors.find(Path::getFilenameExtensionInLowerCase(path));
if (it != _reporterrors.end()) {
return it->second;
}
// assume true if we don't know as it'll be a core-type (c/cpp etc)
return true;
}
bool ignorefunction(const std::string &function) const {
const std::map<std::string, bool>::const_iterator it = _ignorefunction.find(function);
return (it != _ignorefunction.end() && it->second);
}
bool isexecutableblock(const std::string &file, const std::string &token) const {
bool isexecblock;
const std::map<std::string, CodeBlock>::const_iterator map_it
= _executableblocks.find(Path::getFilenameExtensionInLowerCase(file));
if (map_it != _executableblocks.end()) {
isexecblock = map_it->second.isBlock(token);
} else {
isexecblock = false;
}
return isexecblock;
}
int blockstartoffset(const std::string &file) const {
int offset = -1;
const std::map<std::string, CodeBlock>::const_iterator map_it
= _executableblocks.find(Path::getFilenameExtensionInLowerCase(file));
if (map_it != _executableblocks.end()) {
offset = map_it->second.offset();
}
return offset;
}
std::string blockstart(const std::string &file) const {
std::string start;
const std::map<std::string, CodeBlock>::const_iterator map_it
= _executableblocks.find(Path::getFilenameExtensionInLowerCase(file));
if (map_it != _executableblocks.end()) {
start = map_it->second.start();
}
return start;
}
std::string blockend(const std::string &file) const {
std::string end;
const std::map<std::string, CodeBlock>::const_iterator map_it
= _executableblocks.find(Path::getFilenameExtensionInLowerCase(file));
if (map_it != _executableblocks.end()) {
end = map_it->second.end();
}
return end;
}
bool iskeyword(const std::string &file, const std::string &keyword) const {
bool iskw;
const std::map<std::string, std::list<std::string> >::const_iterator it =
_keywords.find(Path::getFilenameExtensionInLowerCase(file));
if (it != _keywords.end()) {
const std::list<std::string> list = it->second;
const std::list<std::string>::const_iterator list_it =
std::find(list.begin(), list.end(), keyword);
iskw = list_it != list.end();
} else {
iskw = false;
}
return iskw;
}
bool isexporter(const std::string &prefix) const {
const std::map<std::string, ExportedFunctions>::const_iterator it =
_exporters.find(prefix);
return it != _exporters.end();
}
bool isexportedprefix(const std::string &prefix, const std::string &token) const {
const std::map<std::string, ExportedFunctions>::const_iterator it = _exporters.find(prefix);
std::list<std::string>::const_iterator token_it;
if (it != _exporters.end()) {
return it->second.isPrefix(token);
} else
return false;
}
bool isexportedsuffix(const std::string &prefix, const std::string &token) const {
const std::map<std::string, ExportedFunctions>::const_iterator it = _exporters.find(prefix);
std::list<std::string>::const_iterator token_it;
if (it != _exporters.end()) {
return it->second.isSuffix(token);
} else
return false;
}
bool isimporter(const std::string& file, const std::string &importer) const {
bool isImporter;
const std::map<std::string, std::list<std::string> >::const_iterator it =
_importers.find(Path::getFilenameExtensionInLowerCase(file));
if (it != _importers.end()) {
const std::list<std::string> list = it->second;
const std::list<std::string>::const_iterator it2 =
std::find(list.begin(), list.end(), importer);
isImporter = (it2 != list.end());
} else {
isImporter = false;
}
return isImporter;
}
bool isreflection(const std::string& file, const std::string &token) const {
bool isReflecMethod;
const std::map<std::string,std::map<std::string,int> >::const_iterator it
= _reflection.find(Path::getFilenameExtensionInLowerCase(file));
if (it != _reflection.end()) {
const std::map<std::string,int>::const_iterator it2 =
it->second.find(token);
isReflecMethod = it2 != it->second.end();
} else {
isReflecMethod = false;
}
return isReflecMethod;
}
int reflectionArgument(const std::string& file, const std::string &token) const {
int argIndex = -1;
const std::map<std::string,std::map<std::string,int> >::const_iterator it
= _reflection.find(Path::getFilenameExtensionInLowerCase(file));
if (it != _reflection.end()) {
const std::map<std::string,int>::const_iterator it2 =
it->second.find(token);
if (it2 != it->second.end()) {
argIndex = it2->second;
}
}
return argIndex;
}
std::set<std::string> returnuninitdata;
private:
class ExportedFunctions {
public:
void addPrefix(const std::string& prefix) {
_prefixes.push_back(prefix);
}
void addSuffix(const std::string& suffix) {
_suffixes.push_back(suffix);
}
bool isPrefix(const std::string& prefix) const {
return std::find(_prefixes.begin(), _prefixes.end(), prefix)
!= _prefixes.end();
}
bool isSuffix(const std::string& suffix) const {
return std::find(_suffixes.begin(), _suffixes.end(), suffix)
!= _suffixes.end();
}
private:
std::list<std::string> _prefixes;
std::list<std::string> _suffixes;
};
class CodeBlock {
public:
void setStart(const std::string& s) {
_start = s;
}
void setEnd(const std::string& e) {
_end = e;
}
void setOffset(const int o) {
_offset = o;
}
void addBlock(const std::string& blockName) {
_blocks.push_back(blockName);
}
std::string start() const {
return _start;
}
std::string end() const {
return _end;
}
int offset() const {
return _offset;
}
bool isBlock(const std::string& blockName) const {
return std::find(_blocks.begin(), _blocks.end(), blockName)
!= _blocks.end();
}
private:
std::string _start;
std::string _end;
int _offset;
std::list<std::string> _blocks;
};
int allocid;
std::map<std::string, int> _alloc; // allocation functions
std::map<std::string, int> _dealloc; // deallocation functions
std::map<std::string, bool> _noreturn; // is function noreturn?
std::map<std::string, bool> _ignorefunction; // ignore functions/macros from a library (gtk, qt etc)
std::map<std::string, bool> _reporterrors;
std::list<std::string> _fileextensions; // accepted file extensions
std::map<std::string, std::list<std::string> > _keywords; // keywords for code in the library
std::map<std::string, CodeBlock> _executableblocks; // keywords for blocks of executable code
std::map<std::string, ExportedFunctions> _exporters; // keywords that export variables/functions to libraries (meta-code/macros)
std::map<std::string, std::list<std::string> > _importers; // keywords that import variables/functions
std::map<std::string,std::map<std::string,int> > _reflection; // invokation of reflection
const ArgumentChecks * getarg(const std::string &functionName, int argnr) const {
std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it1;

View File

@ -22,6 +22,7 @@
#include <cstring>
#include <cctype>
#include "path.h"
#include "library.h"
/** Is the filesystem case insensitive? */
static bool caseInsensitiveFilesystem()
@ -206,9 +207,9 @@ bool Path::isCPP(const std::string &path)
return (getFilenameExtension(path) == ".C");
}
bool Path::acceptFile(const std::string &path)
bool Path::acceptFile(const std::string &path, const class Library *library)
{
return !Path::isHeader(path) && (Path::isCPP(path) || Path::isC(path));
return !Path::isHeader(path) && (Path::isCPP(path) || Path::isC(path) || (library ? library->acceptFile(path) : false));
}
bool Path::isHeader(const std::string &path)

View File

@ -109,7 +109,7 @@ public:
* @param filename filename to check. path info is optional
* @return returns true if the file extension indicates it should be checked
*/
static bool acceptFile(const std::string &filename);
static bool acceptFile(const std::string &filename, const class Library *library = 0);
/**
* @brief Identify language based on file extension.

View File

@ -18,6 +18,7 @@
#include "testsuite.h"
#include "filelister.h"
#include "settings.h"
#include <fstream>
#ifndef _WIN32
@ -75,7 +76,8 @@ private:
void recursiveAddFiles() const {
// Recursively add add files..
std::map<std::string, std::size_t> files;
FileLister::recursiveAddFiles(files, ".");
Settings settings; // TODO(struscott): Pull in settings
FileLister::recursiveAddFiles(files, ".", &settings.library);
// In case there are leading "./"..
for (std::map<std::string, std::size_t>::iterator i = files.begin(); i != files.end();) {

View File

@ -71,7 +71,7 @@ private:
// Check for unused functions..
CheckUnusedFunctions checkUnusedFunctions(&tokenizer, &settings, this);
checkUnusedFunctions.parseTokens(tokenizer);
checkUnusedFunctions.parseTokens(tokenizer, "someFile.c", &settings);
checkUnusedFunctions.check(this);
}
@ -262,7 +262,7 @@ private:
std::istringstream istr(code);
tokenizer.tokenize(istr, fname.str().c_str());
c.parseTokens(tokenizer);
c.parseTokens(tokenizer, "someFile.c", &settings);
}
// Check for unused functions..