Extended Qt support through Library
This commit is contained in:
parent
fc26de89a9
commit
6806fd8135
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
142
lib/library.cpp
142
lib/library.cpp
|
@ -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;
|
||||
}
|
||||
|
|
234
lib/library.h
234
lib/library.h
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();) {
|
||||
|
|
|
@ -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..
|
||||
|
|
Loading…
Reference in New Issue