Fix Ticket #30, Need a way to specify include file folders (-I parameter was added)
This commit is contained in:
parent
a9e84c5cd5
commit
e897637c7a
|
@ -104,6 +104,7 @@ man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
|
|||
<command>&dhpackage;</command>
|
||||
<arg choice="opt"><option>--all</option></arg>
|
||||
<arg choice="opt"><option>--quiet</option></arg>
|
||||
<arg choice="opt"><option>-Idir</option></arg>
|
||||
<arg choice="opt"><option>--style</option></arg>
|
||||
<arg choice="opt"><option>--verbose</option></arg>
|
||||
<arg choice="opt"><option>--force</option></arg>
|
||||
|
@ -133,6 +134,21 @@ man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
|
|||
found a bug. When this option is given, all messages are shown.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-f</option></term>
|
||||
<term><option>--force</option></term>
|
||||
<listitem>
|
||||
<para>Force checking of files that have a lot of configurations. Error is printed if such a file is found so there is no reason to use this by
|
||||
default.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-I <dir></option></term>
|
||||
<listitem>
|
||||
<para>Give include path. Give several -I parameters to give several paths. First given path is checked first. If paths are relative to source
|
||||
files, this is not needed.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-q</option></term>
|
||||
<term><option>--quiet</option></term>
|
||||
|
@ -154,14 +170,6 @@ man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
|
|||
<para>More detailed error reports</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-f</option></term>
|
||||
<term><option>--force</option></term>
|
||||
<listitem>
|
||||
<para>Force checking of files that have a lot of configurations. Error is printed if such a file is found so there is no reason to use this by
|
||||
default.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
<refsect1 id="author">
|
||||
|
|
|
@ -95,6 +95,35 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
|
|||
else if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--force") == 0)
|
||||
_settings._force = true;
|
||||
|
||||
// Include paths
|
||||
else if (strcmp(argv[i], "-I") == 0 || strncmp(argv[i], "-I", 2) == 0)
|
||||
{
|
||||
std::string path;
|
||||
|
||||
// "-I path/"
|
||||
if (strcmp(argv[i], "-I") == 0)
|
||||
{
|
||||
++i;
|
||||
if (i >= argc)
|
||||
return "cppcheck: argument to '-I' is missing\n";
|
||||
|
||||
path = argv[i];
|
||||
}
|
||||
|
||||
// "-Ipath/"
|
||||
else
|
||||
{
|
||||
path = argv[i];
|
||||
path = path.substr(2);
|
||||
}
|
||||
|
||||
// If path doesn't end with / or \, add it
|
||||
if (path[path.length()-1] != '/' && path[path.length()-1] != '\\')
|
||||
path += '/';
|
||||
|
||||
_includePaths.push_back(path);
|
||||
}
|
||||
|
||||
else
|
||||
pathnames.push_back(argv[i]);
|
||||
}
|
||||
|
@ -115,7 +144,7 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
|
|||
"A tool for static C/C++ code analysis\n"
|
||||
"\n"
|
||||
"Syntax:\n"
|
||||
" cppcheck [--all] [--force] [--quiet] [--style] [--verbose] [file or path1] [file or path]\n"
|
||||
" cppcheck [--all] [--force] [-Idir] [--quiet] [--style] [--verbose] [file or path1] [file or path]\n"
|
||||
"\n"
|
||||
"If path is given instead of filename, *.cpp, *.cxx, *.cc, *.c++ and *.c files\n"
|
||||
"are checked recursively from given directory.\n\n"
|
||||
|
@ -123,6 +152,9 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
|
|||
" -a, --all Make the checking more sensitive. More bugs are detected,\n"
|
||||
" but there are also more false positives\n"
|
||||
" -f, --force Force checking on files that have \"too many\" configurations\n"
|
||||
" -I <dir> Give include path. Give several -I parameters to give several\n"
|
||||
" paths. First given path is checked first. If paths are\n"
|
||||
" relative to source files, this is not needed.\n"
|
||||
" -q, --quiet Only print error messages\n"
|
||||
" -s, --style Check coding style\n"
|
||||
" -v, --verbose More detailed error reports\n"
|
||||
|
@ -133,7 +165,9 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
|
|||
" # Recursively check ../myproject/ and print only most fatal errors:\n"
|
||||
" cppcheck --quiet ../myproject/\n"
|
||||
" # Check only files one.cpp and two.cpp and give all information there is:\n"
|
||||
" cppcheck -v -a -s one.cpp two.cpp\n";
|
||||
" cppcheck -v -a -s one.cpp two.cpp\n"
|
||||
" # Check f.cpp and search include files from inc1/ and inc2/:\n"
|
||||
" cppcheck -I inc1/ -I inc2/ f.cpp\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
@ -159,13 +193,13 @@ unsigned int CppCheck::check()
|
|||
{
|
||||
// File content was given as a string
|
||||
std::istringstream iss(_fileContents[ _filenames[c] ]);
|
||||
preprocessor.preprocess(iss, filedata, configurations, fname);
|
||||
preprocessor.preprocess(iss, filedata, configurations, fname, _includePaths);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only file name was given, read the content from file
|
||||
std::ifstream fin(fname.c_str());
|
||||
preprocessor.preprocess(fin, filedata, configurations, fname);
|
||||
preprocessor.preprocess(fin, filedata, configurations, fname, _includePaths);
|
||||
}
|
||||
|
||||
int checkCount = 0;
|
||||
|
|
|
@ -123,6 +123,10 @@ private:
|
|||
|
||||
/** Current configuration */
|
||||
std::string cfg;
|
||||
|
||||
/** List of include paths, e.g. "my/includes/" which should be used
|
||||
for finding include files inside source files. */
|
||||
std::list<std::string> _includePaths;
|
||||
};
|
||||
|
||||
#endif // CPPCHECK_H
|
||||
|
|
|
@ -173,12 +173,12 @@ std::string Preprocessor::read(std::istream &istr)
|
|||
|
||||
return code.str();
|
||||
}
|
||||
#include <iostream>
|
||||
void Preprocessor::preprocess(std::istream &istr, std::map<std::string, std::string> &result, const std::string &filename)
|
||||
|
||||
void Preprocessor::preprocess(std::istream &istr, std::map<std::string, std::string> &result, const std::string &filename, const std::list<std::string> &includePaths)
|
||||
{
|
||||
std::list<std::string> configs;
|
||||
std::string data;
|
||||
preprocess(istr, data, configs, filename);
|
||||
preprocess(istr, data, configs, filename, includePaths);
|
||||
for (std::list<std::string>::const_iterator it = configs.begin(); it != configs.end(); ++it)
|
||||
result[ *it ] = Preprocessor::getcode(data, *it);
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ std::string Preprocessor::replaceIfDefined(const std::string &str)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void Preprocessor::preprocess(std::istream &istr, std::string &processedFile, std::list<std::string> &resultConfigurations, const std::string &filename)
|
||||
void Preprocessor::preprocess(std::istream &istr, std::string &processedFile, std::list<std::string> &resultConfigurations, const std::string &filename, const std::list<std::string> &includePaths)
|
||||
{
|
||||
processedFile = read(istr);
|
||||
|
||||
|
@ -242,7 +242,7 @@ void Preprocessor::preprocess(std::istream &istr, std::string &processedFile, st
|
|||
// Remove space characters that are after or before new line character
|
||||
processedFile = removeSpaceNearNL(processedFile);
|
||||
|
||||
handleIncludes(processedFile, filename);
|
||||
handleIncludes(processedFile, filename, includePaths);
|
||||
|
||||
processedFile = replaceIfDefined(processedFile);
|
||||
|
||||
|
@ -470,7 +470,7 @@ std::string Preprocessor::getHeaderFileName(const std::string &str)
|
|||
return result;
|
||||
}
|
||||
|
||||
void Preprocessor::handleIncludes(std::string &code, const std::string &filename)
|
||||
void Preprocessor::handleIncludes(std::string &code, const std::string &filename, const std::list<std::string> &includePaths)
|
||||
{
|
||||
// std::string line;
|
||||
std::string path = filename;
|
||||
|
@ -496,9 +496,26 @@ void Preprocessor::handleIncludes(std::string &code, const std::string &filename
|
|||
continue;
|
||||
|
||||
// filename contains now a file name e.g. "menu.h"
|
||||
filename = path + filename;
|
||||
std::ifstream fin(filename.c_str());
|
||||
std::string processedFile = Preprocessor::read(fin);
|
||||
std::string processedFile;
|
||||
for (std::list<std::string>::const_iterator iter = includePaths.begin(); iter != includePaths.end(); ++iter)
|
||||
{
|
||||
std::ifstream fin;
|
||||
fin.open((*iter + filename).c_str());
|
||||
if (fin.is_open())
|
||||
{
|
||||
filename = *iter + filename;
|
||||
processedFile = Preprocessor::read(fin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (processedFile.length() == 0)
|
||||
{
|
||||
filename = path + filename;
|
||||
std::ifstream fin(filename.c_str());
|
||||
processedFile = Preprocessor::read(fin);
|
||||
}
|
||||
|
||||
if (processedFile.length() > 0)
|
||||
{
|
||||
// Replace all tabs with spaces..
|
||||
|
|
|
@ -38,8 +38,13 @@ public:
|
|||
* @param istr The (file/string) stream to read from.
|
||||
* @param result The map that will get the results
|
||||
* @param filename The name of the file to check e.g. "src/main.cpp"
|
||||
* @param includePaths List of paths where incude files should be searched from,
|
||||
* single path can be e.g. in format "include/".
|
||||
* There must be a path separator at the end. Default parameter is empty list.
|
||||
* Note that if path from given filename is also extracted and that is used as
|
||||
* a last include path if include file was not found from earlier paths.
|
||||
*/
|
||||
void preprocess(std::istream &istr, std::map<std::string, std::string> &result, const std::string &filename);
|
||||
void preprocess(std::istream &istr, std::map<std::string, std::string> &result, const std::string &filename, const std::list<std::string> &includePaths = std::list<std::string>());
|
||||
|
||||
/**
|
||||
* Extract the code for each configuration. Use this with getcode() to get the
|
||||
|
@ -52,8 +57,13 @@ public:
|
|||
* @param resultConfigurations List of configurations. Pass these one by one
|
||||
* to getcode() with processedFile.
|
||||
* @param filename The name of the file to check e.g. "src/main.cpp"
|
||||
* @param includePaths List of paths where incude files should be searched from,
|
||||
* single path can be e.g. in format "include/".
|
||||
* There must be a path separator at the end. Default parameter is empty list.
|
||||
* Note that if path from given filename is also extracted and that is used as
|
||||
* a last include path if include file was not found from earlier paths.
|
||||
*/
|
||||
void preprocess(std::istream &istr, std::string &processedFile, std::list<std::string> &resultConfigurations, const std::string &filename);
|
||||
void preprocess(std::istream &istr, std::string &processedFile, std::list<std::string> &resultConfigurations, const std::string &filename, const std::list<std::string> &includePaths);
|
||||
|
||||
/** Just read the code into a string. Perform simple cleanup of the code */
|
||||
static std::string read(std::istream &istr);
|
||||
|
@ -99,9 +109,14 @@ private:
|
|||
* file
|
||||
* @param code The source code to modify
|
||||
* @param filename The name of the file to check e.g. "src/main.cpp"
|
||||
* @param includePaths List of paths where incude files should be searched from,
|
||||
* single path can be e.g. in format "include/".
|
||||
* There must be a path separator at the end. Default parameter is empty list.
|
||||
* Note that if path from given filename is also extracted and that is used as
|
||||
* a last include path if include file was not found from earlier paths.
|
||||
* @return modified source code
|
||||
*/
|
||||
static void handleIncludes(std::string &code, const std::string &filename);
|
||||
static void handleIncludes(std::string &code, const std::string &filename, const std::list<std::string> &includePaths);
|
||||
|
||||
/**
|
||||
* Returns the string between double quote characters.
|
||||
|
|
Loading…
Reference in New Issue