Fixed #912 (### Unlogged error at Tokenizer::syntaxError: Invalid number of character (())
This commit is contained in:
parent
d5e7d688d2
commit
7890589693
|
@ -26,7 +26,6 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -161,7 +160,15 @@ void Preprocessor::writeError(const std::string &fileName, const std::string &co
|
||||||
{
|
{
|
||||||
if (lineNumbers.empty() || fileIndexes.empty())
|
if (lineNumbers.empty() || fileIndexes.empty())
|
||||||
{
|
{
|
||||||
std::cerr << "####### Preprocessor bug! #######\n";
|
std::ostringstream line;
|
||||||
|
line << __LINE__;
|
||||||
|
|
||||||
|
ErrorLogger::ErrorMessage errmsg;
|
||||||
|
errmsg._severity = "error";
|
||||||
|
errmsg._msg = "####### Preprocessor bug! #######";
|
||||||
|
errmsg._id = "preprocessor" + line.str();
|
||||||
|
errorLogger->reportErr(errmsg);
|
||||||
|
|
||||||
std::exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,7 +714,7 @@ void Preprocessor::preprocess(std::istream &istr, std::string &processedFile, st
|
||||||
processedFile = replaceIfDefined(processedFile);
|
processedFile = replaceIfDefined(processedFile);
|
||||||
|
|
||||||
// Get all possible configurations..
|
// Get all possible configurations..
|
||||||
resultConfigurations = getcfgs(processedFile);
|
resultConfigurations = getcfgs(processedFile, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -743,7 +750,7 @@ std::string Preprocessor::getdef(std::string line, bool def)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::list<std::string> Preprocessor::getcfgs(const std::string &filedata)
|
std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const std::string &filename)
|
||||||
{
|
{
|
||||||
std::list<std::string> ret;
|
std::list<std::string> ret;
|
||||||
ret.push_back("");
|
ret.push_back("");
|
||||||
|
@ -757,10 +764,13 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata)
|
||||||
// 0=>Source file, 1=>Included by source file, 2=>included by header that was included by source file, etc
|
// 0=>Source file, 1=>Included by source file, 2=>included by header that was included by source file, etc
|
||||||
int filelevel = 0;
|
int filelevel = 0;
|
||||||
|
|
||||||
|
unsigned int linenr = 0;
|
||||||
std::istringstream istr(filedata);
|
std::istringstream istr(filedata);
|
||||||
std::string line;
|
std::string line;
|
||||||
while (getline(istr, line))
|
while (getline(istr, line))
|
||||||
{
|
{
|
||||||
|
++linenr;
|
||||||
|
|
||||||
if (line.compare(0, 6, "#file ") == 0)
|
if (line.compare(0, 6, "#file ") == 0)
|
||||||
{
|
{
|
||||||
++filelevel;
|
++filelevel;
|
||||||
|
@ -792,6 +802,36 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata)
|
||||||
std::string def = getdef(line, true) + getdef(line, false);
|
std::string def = getdef(line, true) + getdef(line, false);
|
||||||
if (!def.empty())
|
if (!def.empty())
|
||||||
{
|
{
|
||||||
|
int par = 0;
|
||||||
|
for (std::string::size_type pos = 0; pos < def.length(); ++pos)
|
||||||
|
{
|
||||||
|
if (def[pos] == '(')
|
||||||
|
++par;
|
||||||
|
else if (def[pos] == ')')
|
||||||
|
{
|
||||||
|
--par;
|
||||||
|
if (par < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (par != 0)
|
||||||
|
{
|
||||||
|
std::ostringstream line;
|
||||||
|
line << __LINE__;
|
||||||
|
|
||||||
|
ErrorLogger::ErrorMessage errmsg;
|
||||||
|
ErrorLogger::ErrorMessage::FileLocation loc;
|
||||||
|
loc.file = filename;
|
||||||
|
loc.line = linenr;
|
||||||
|
errmsg._callStack.push_back(loc);
|
||||||
|
errmsg._severity = "error";
|
||||||
|
errmsg._msg = "mismatching number of '(' and ')' in this line: " + def;
|
||||||
|
errmsg._id = "preprocessor" + line.str();
|
||||||
|
_errorLogger->reportErr(errmsg);
|
||||||
|
ret.clear();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (! deflist.empty() && line.find("#elif ") == 0)
|
if (! deflist.empty() && line.find("#elif ") == 0)
|
||||||
deflist.pop_back();
|
deflist.pop_back();
|
||||||
deflist.push_back(def);
|
deflist.push_back(def);
|
||||||
|
@ -812,7 +852,6 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata)
|
||||||
def += *it;
|
def += *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::find(ret.begin(), ret.end(), def) == ret.end())
|
if (std::find(ret.begin(), ret.end(), def) == ret.end())
|
||||||
ret.push_back(def);
|
ret.push_back(def);
|
||||||
}
|
}
|
||||||
|
@ -878,11 +917,22 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata)
|
||||||
|
|
||||||
if (s.find("&&") != std::string::npos)
|
if (s.find("&&") != std::string::npos)
|
||||||
{
|
{
|
||||||
Tokenizer tokenizer;
|
Tokenizer tokenizer(_settings, _errorLogger);
|
||||||
std::istringstream istr(s.c_str());
|
std::istringstream istr(s.c_str());
|
||||||
if (!tokenizer.tokenize(istr, ""))
|
if (!tokenizer.tokenize(istr, filename.c_str()))
|
||||||
{
|
{
|
||||||
std::cerr << "Error parsing this:\n" << s << "\n\n";
|
std::ostringstream line;
|
||||||
|
line << __LINE__;
|
||||||
|
|
||||||
|
ErrorLogger::ErrorMessage errmsg;
|
||||||
|
ErrorLogger::ErrorMessage::FileLocation loc;
|
||||||
|
loc.file = filename;
|
||||||
|
loc.line = 1;
|
||||||
|
errmsg._callStack.push_back(loc);
|
||||||
|
errmsg._severity = "error";
|
||||||
|
errmsg._msg = "Error parsing this: " + s;
|
||||||
|
errmsg._id = "preprocessor" + line.str();
|
||||||
|
_errorLogger->reportErr(errmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1642,7 +1692,16 @@ std::string Preprocessor::expandMacros(std::string code, const std::string &file
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cerr << "### Preprocessor::expandMacros() loop limit exceeded.";
|
{
|
||||||
|
std::ostringstream line;
|
||||||
|
line << __LINE__;
|
||||||
|
|
||||||
|
ErrorLogger::ErrorMessage errmsg;
|
||||||
|
errmsg._severity = "error";
|
||||||
|
errmsg._msg = "### Preprocessor::expandMacros() loop limit exceeded.";
|
||||||
|
errmsg._id = "preprocessor" + line.str();
|
||||||
|
errorLogger->reportErr(errmsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -129,7 +129,7 @@ private:
|
||||||
* Get all possible configurations sorted in alphabetical order.
|
* Get all possible configurations sorted in alphabetical order.
|
||||||
* By looking at the ifdefs and ifndefs in filedata
|
* By looking at the ifdefs and ifndefs in filedata
|
||||||
*/
|
*/
|
||||||
std::list<std::string> getcfgs(const std::string &filedata);
|
std::list<std::string> getcfgs(const std::string &filedata, const std::string &filename);
|
||||||
|
|
||||||
static std::string getdef(std::string line, bool def);
|
static std::string getdef(std::string line, bool def);
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,7 @@ private:
|
||||||
TEST_CASE(if_cond3);
|
TEST_CASE(if_cond3);
|
||||||
TEST_CASE(if_cond4);
|
TEST_CASE(if_cond4);
|
||||||
TEST_CASE(if_cond5);
|
TEST_CASE(if_cond5);
|
||||||
|
TEST_CASE(if_cond6);
|
||||||
|
|
||||||
TEST_CASE(multiline1);
|
TEST_CASE(multiline1);
|
||||||
TEST_CASE(multiline2);
|
TEST_CASE(multiline2);
|
||||||
|
@ -778,6 +779,25 @@ private:
|
||||||
ASSERT_EQUALS("\nab\n\ncd\n\nef\n\n", actual["A;B"]);
|
ASSERT_EQUALS("\nab\n\ncd\n\nef\n\n", actual["A;B"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void if_cond6()
|
||||||
|
{
|
||||||
|
const char filedata[] = "\n"
|
||||||
|
"#if defined(A) && defined(B))\n"
|
||||||
|
"#endif\n";
|
||||||
|
|
||||||
|
errout.str("");
|
||||||
|
|
||||||
|
// Preprocess => actual result..
|
||||||
|
std::istringstream istr(filedata);
|
||||||
|
std::map<std::string, std::string> actual;
|
||||||
|
const Settings settings;
|
||||||
|
Preprocessor preprocessor(&settings, this);
|
||||||
|
preprocessor.preprocess(istr, actual, "file.c");
|
||||||
|
|
||||||
|
// Compare results..
|
||||||
|
ASSERT_EQUALS("[file.c:2]: (error) mismatching number of '(' and ')' in this line: defined(A)&&defined(B))\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void multiline1()
|
void multiline1()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue