Fix ticket #242 (Preprocessor: Bail out on failure instead of terminating the program)
http://apps.sourceforge.net/trac/cppcheck/ticket/242
This commit is contained in:
parent
3b0643a000
commit
7a11f0e61f
|
@ -327,7 +327,7 @@ unsigned int CppCheck::check()
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg = *it;
|
cfg = *it;
|
||||||
std::string codeWithoutCfg = Preprocessor::getcode(filedata, *it);
|
std::string codeWithoutCfg = Preprocessor::getcode(filedata, *it, fname, _errorLogger);
|
||||||
|
|
||||||
// If only errors are printed, print filename after the check
|
// If only errors are printed, print filename after the check
|
||||||
if (_settings._errorsOnly == false && it != configurations.begin())
|
if (_settings._errorsOnly == false && it != configurations.begin())
|
||||||
|
|
|
@ -184,13 +184,13 @@ std::string Preprocessor::read(std::istream &istr)
|
||||||
return code.str();
|
return code.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Preprocessor::preprocess(std::istream &istr, std::map<std::string, std::string> &result, const std::string &filename, const std::list<std::string> &includePaths)
|
void Preprocessor::preprocess(std::istream &istr, std::map<std::string, std::string> &result, const std::string &filename, const std::list<std::string> &includePaths, ErrorLogger *errorLogger)
|
||||||
{
|
{
|
||||||
std::list<std::string> configs;
|
std::list<std::string> configs;
|
||||||
std::string data;
|
std::string data;
|
||||||
preprocess(istr, data, configs, filename, includePaths);
|
preprocess(istr, data, configs, filename, includePaths);
|
||||||
for (std::list<std::string>::const_iterator it = configs.begin(); it != configs.end(); ++it)
|
for (std::list<std::string>::const_iterator it = configs.begin(); it != configs.end(); ++it)
|
||||||
result[ *it ] = Preprocessor::getcode(data, *it);
|
result[ *it ] = Preprocessor::getcode(data, *it, filename, errorLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Preprocessor::removeSpaceNearNL(const std::string &str)
|
std::string Preprocessor::removeSpaceNearNL(const std::string &str)
|
||||||
|
@ -384,7 +384,7 @@ bool Preprocessor::match_cfg_def(std::string cfg, const std::string &def)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string Preprocessor::getcode(const std::string &filedata, std::string cfg)
|
std::string Preprocessor::getcode(const std::string &filedata, std::string cfg, const std::string &filename, ErrorLogger *errorLogger)
|
||||||
{
|
{
|
||||||
std::ostringstream ret;
|
std::ostringstream ret;
|
||||||
|
|
||||||
|
@ -467,7 +467,7 @@ std::string Preprocessor::getcode(const std::string &filedata, std::string cfg)
|
||||||
ret << line << "\n";
|
ret << line << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return expandMacros(ret.str());
|
return expandMacros(ret.str(), filename, errorLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Preprocessor::getHeaderFileName(const std::string &str)
|
std::string Preprocessor::getHeaderFileName(const std::string &str)
|
||||||
|
@ -708,7 +708,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string Preprocessor::expandMacros(std::string code)
|
std::string Preprocessor::expandMacros(std::string code, const std::string &filename, ErrorLogger *errorLogger)
|
||||||
{
|
{
|
||||||
// Search for macros and expand them..
|
// Search for macros and expand them..
|
||||||
std::string::size_type defpos = 0;
|
std::string::size_type defpos = 0;
|
||||||
|
@ -780,9 +780,21 @@ std::string Preprocessor::expandMacros(std::string code)
|
||||||
|
|
||||||
if (!code[pos1])
|
if (!code[pos1])
|
||||||
{
|
{
|
||||||
// This should not happen, if it does, there is a bug in cppcheck.
|
// End of file was reached without finding pair
|
||||||
std::cout << "\n\n####### There is a bug in preprocessor.cpp that can cause crash, shutting down.\n\n" << std::endl;
|
if (errorLogger)
|
||||||
std::exit(0);
|
{
|
||||||
|
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
|
||||||
|
ErrorLogger::ErrorMessage::FileLocation loc;
|
||||||
|
loc.line = 0;
|
||||||
|
loc.file = filename;
|
||||||
|
locationList.push_back(loc);
|
||||||
|
errorLogger->reportErr(
|
||||||
|
ErrorLogger::ErrorMessage(locationList,
|
||||||
|
"error",
|
||||||
|
std::string("No pair for character (") + ch + "). Can't process file. File is either invalid or unicode, which is currently not supported.",
|
||||||
|
"noQuoteCharPair"));
|
||||||
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <istream>
|
#include <istream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include "errorlogger.h"
|
||||||
|
|
||||||
|
|
||||||
class Preprocessor
|
class Preprocessor
|
||||||
|
@ -44,7 +45,7 @@ public:
|
||||||
* Note that if path from given filename is also extracted and that is used as
|
* 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.
|
* 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, const std::list<std::string> &includePaths = std::list<std::string>());
|
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>(), ErrorLogger *errorLogger = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the code for each configuration. Use this with getcode() to get the
|
* Extract the code for each configuration. Use this with getcode() to get the
|
||||||
|
@ -71,7 +72,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Get preprocessed code for a given configuration
|
* Get preprocessed code for a given configuration
|
||||||
*/
|
*/
|
||||||
static std::string getcode(const std::string &filedata, std::string cfg);
|
static std::string getcode(const std::string &filedata, std::string cfg, const std::string &filename, ErrorLogger *errorLogger);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ protected:
|
||||||
*/
|
*/
|
||||||
static std::string replaceIfDefined(const std::string &str);
|
static std::string replaceIfDefined(const std::string &str);
|
||||||
|
|
||||||
static std::string expandMacros(std::string code);
|
static std::string expandMacros(std::string code, const std::string &filename, ErrorLogger *errorLogger);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
extern std::ostringstream errout;
|
||||||
|
|
||||||
class TestPreprocessor : public TestFixture
|
class TestPreprocessor : public TestFixture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -42,9 +44,9 @@ public:
|
||||||
return Preprocessor::replaceIfDefined(str);
|
return Preprocessor::replaceIfDefined(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string expandMacros(std::string code)
|
static std::string expandMacros(std::string code, ErrorLogger *errorLogger = 0)
|
||||||
{
|
{
|
||||||
return Preprocessor::expandMacros(code);
|
return Preprocessor::expandMacros(code, "file.cpp", errorLogger);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -112,6 +114,7 @@ private:
|
||||||
TEST_CASE(ifdefwithfile);
|
TEST_CASE(ifdefwithfile);
|
||||||
TEST_CASE(pragma);
|
TEST_CASE(pragma);
|
||||||
TEST_CASE(endifsemicolon);
|
TEST_CASE(endifsemicolon);
|
||||||
|
TEST_CASE(missing_doublequote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -816,6 +819,21 @@ private:
|
||||||
"\n"
|
"\n"
|
||||||
"}\n", actual[""]);
|
"}\n", actual[""]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void missing_doublequote()
|
||||||
|
{
|
||||||
|
const char filedata[] = "#define a\n"
|
||||||
|
"#ifdef 1\n"
|
||||||
|
"\"\n"
|
||||||
|
"#endif\n";
|
||||||
|
|
||||||
|
// expand macros..
|
||||||
|
errout.str("");
|
||||||
|
std::string actual = OurPreprocessor::expandMacros(filedata, this);
|
||||||
|
|
||||||
|
ASSERT_EQUALS("", actual);
|
||||||
|
ASSERT_EQUALS("[file.cpp:0]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported.\n", errout.str());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestPreprocessor)
|
REGISTER_TEST(TestPreprocessor)
|
||||||
|
|
Loading…
Reference in New Issue