Fix ticket #312 (division by pointer value causes wrong tokenizing)
http://apps.sourceforge.net/trac/cppcheck/ticket/312
This commit is contained in:
parent
2508f3c721
commit
36cdac1b96
|
@ -81,7 +81,7 @@ std::string Preprocessor::read(std::istream &istr)
|
|||
// Skip spaces after ' ' and after '#'
|
||||
if (ch == ' ' && ignoreSpace)
|
||||
continue;
|
||||
ignoreSpace = bool(ch == ' ' || ch == '#' || ch == '/' || ch == '\n');
|
||||
ignoreSpace = bool(ch == ' ' || ch == '#' || ch == '\n');
|
||||
|
||||
if (needSpace)
|
||||
{
|
||||
|
@ -148,8 +148,8 @@ std::string Preprocessor::removeComments(const std::string &str)
|
|||
// when this is encountered the <backspace><newline> will be "skipped".
|
||||
// on the next <newline>, extra newlines will be added
|
||||
unsigned int newlines = 0;
|
||||
|
||||
std::ostringstream code;
|
||||
char previous = 0;
|
||||
for (std::string::size_type i = 0; i < str.length(); ++i)
|
||||
{
|
||||
char ch = str[i];
|
||||
|
@ -157,25 +157,20 @@ std::string Preprocessor::removeComments(const std::string &str)
|
|||
throw std::runtime_error("The code contains characters that are unhandled");
|
||||
|
||||
// Remove comments..
|
||||
if (ch == '/')
|
||||
if (str.compare(i, 2, "//", 0, 2) == 0)
|
||||
{
|
||||
++i;
|
||||
char chNext = str[i];
|
||||
i = str.find('\n', i);
|
||||
if (i == std::string::npos)
|
||||
break;
|
||||
|
||||
if (chNext == '/')
|
||||
{
|
||||
while (i < str.length() && ch != '\n')
|
||||
{
|
||||
++i;
|
||||
ch = str[i];
|
||||
}
|
||||
code << "\n";
|
||||
previous = '\n';
|
||||
++lineno;
|
||||
}
|
||||
|
||||
else if (chNext == '*')
|
||||
else if (str.compare(i, 2, "/*", 0, 2) == 0)
|
||||
{
|
||||
char chPrev = 0;
|
||||
++i;
|
||||
while (i < str.length() && (chPrev != '*' || ch != '/'))
|
||||
{
|
||||
chPrev = ch;
|
||||
|
@ -184,19 +179,12 @@ std::string Preprocessor::removeComments(const std::string &str)
|
|||
if (ch == '\n')
|
||||
{
|
||||
code << "\n";
|
||||
previous = '\n';
|
||||
++lineno;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (chNext == '\n')
|
||||
++lineno;
|
||||
code << std::string(1, ch) << std::string(1, chNext);
|
||||
}
|
||||
}
|
||||
|
||||
// String or char constants..
|
||||
else if (ch == '\"' || ch == '\'')
|
||||
{
|
||||
|
@ -216,10 +204,14 @@ std::string Preprocessor::removeComments(const std::string &str)
|
|||
{
|
||||
code << std::string(1, chNext);
|
||||
code << std::string(1, chSeq);
|
||||
previous = chSeq;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
code << std::string(1, chNext);
|
||||
previous = chNext;
|
||||
}
|
||||
}
|
||||
while (i < str.length() && chNext != ch);
|
||||
}
|
||||
|
@ -227,14 +219,24 @@ std::string Preprocessor::removeComments(const std::string &str)
|
|||
|
||||
// Just some code..
|
||||
else
|
||||
{
|
||||
if (ch == ' ' && previous == ' ')
|
||||
{
|
||||
// Skip double white space
|
||||
}
|
||||
else
|
||||
{
|
||||
code << std::string(1, ch);
|
||||
previous = ch;
|
||||
}
|
||||
|
||||
|
||||
// if there has been <backspace><newline> sequences, add extra newlines..
|
||||
if (ch == '\n' && newlines > 0)
|
||||
{
|
||||
code << std::string(newlines, '\n');
|
||||
newlines = 0;
|
||||
previous = '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -417,6 +417,23 @@ private:
|
|||
ASSERT_EQUALS("\n\n\n\n", actual[""]);
|
||||
ASSERT_EQUALS(1, static_cast<unsigned int>(actual.size()));
|
||||
}
|
||||
|
||||
{
|
||||
const char filedata[] = "void f()\n"
|
||||
"{\n"
|
||||
" *p = a / *b / *c;\n"
|
||||
"}\n";
|
||||
|
||||
// Preprocess => actual result..
|
||||
std::istringstream istr(filedata);
|
||||
std::map<std::string, std::string> actual;
|
||||
Preprocessor preprocessor;
|
||||
preprocessor.preprocess(istr, actual, "file.c");
|
||||
|
||||
// Compare results..
|
||||
ASSERT_EQUALS("void f()\n{\n*p = a / *b / *c;\n}\n", actual[""]);
|
||||
ASSERT_EQUALS(1, static_cast<unsigned int>(actual.size()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue