Fix ticket #312 (division by pointer value causes wrong tokenizing)

http://apps.sourceforge.net/trac/cppcheck/ticket/312
This commit is contained in:
Reijo Tomperi 2009-05-14 22:53:49 +03:00
parent 2508f3c721
commit 36cdac1b96
2 changed files with 56 additions and 37 deletions

View File

@ -81,7 +81,7 @@ std::string Preprocessor::read(std::istream &istr)
// Skip spaces after ' ' and after '#' // Skip spaces after ' ' and after '#'
if (ch == ' ' && ignoreSpace) if (ch == ' ' && ignoreSpace)
continue; continue;
ignoreSpace = bool(ch == ' ' || ch == '#' || ch == '/' || ch == '\n'); ignoreSpace = bool(ch == ' ' || ch == '#' || ch == '\n');
if (needSpace) if (needSpace)
{ {
@ -148,8 +148,8 @@ std::string Preprocessor::removeComments(const std::string &str)
// when this is encountered the <backspace><newline> will be "skipped". // when this is encountered the <backspace><newline> will be "skipped".
// on the next <newline>, extra newlines will be added // on the next <newline>, extra newlines will be added
unsigned int newlines = 0; unsigned int newlines = 0;
std::ostringstream code; std::ostringstream code;
char previous = 0;
for (std::string::size_type i = 0; i < str.length(); ++i) for (std::string::size_type i = 0; i < str.length(); ++i)
{ {
char ch = str[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"); throw std::runtime_error("The code contains characters that are unhandled");
// Remove comments.. // Remove comments..
if (ch == '/') if (str.compare(i, 2, "//", 0, 2) == 0)
{ {
++i; i = str.find('\n', i);
char chNext = str[i]; if (i == std::string::npos)
break;
if (chNext == '/')
{
while (i < str.length() && ch != '\n')
{
++i;
ch = str[i];
}
code << "\n"; code << "\n";
previous = '\n';
++lineno; ++lineno;
} }
else if (str.compare(i, 2, "/*", 0, 2) == 0)
else if (chNext == '*')
{ {
char chPrev = 0; char chPrev = 0;
++i;
while (i < str.length() && (chPrev != '*' || ch != '/')) while (i < str.length() && (chPrev != '*' || ch != '/'))
{ {
chPrev = ch; chPrev = ch;
@ -184,19 +179,12 @@ std::string Preprocessor::removeComments(const std::string &str)
if (ch == '\n') if (ch == '\n')
{ {
code << "\n"; code << "\n";
previous = '\n';
++lineno; ++lineno;
} }
} }
} }
else
{
if (chNext == '\n')
++lineno;
code << std::string(1, ch) << std::string(1, chNext);
}
}
// String or char constants.. // String or char constants..
else if (ch == '\"' || ch == '\'') 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, chNext);
code << std::string(1, chSeq); code << std::string(1, chSeq);
previous = chSeq;
} }
} }
else else
{
code << std::string(1, chNext); code << std::string(1, chNext);
previous = chNext;
}
} }
while (i < str.length() && chNext != ch); while (i < str.length() && chNext != ch);
} }
@ -227,14 +219,24 @@ std::string Preprocessor::removeComments(const std::string &str)
// Just some code.. // Just some code..
else else
{
if (ch == ' ' && previous == ' ')
{
// Skip double white space
}
else
{ {
code << std::string(1, ch); code << std::string(1, ch);
previous = ch;
}
// if there has been <backspace><newline> sequences, add extra newlines.. // if there has been <backspace><newline> sequences, add extra newlines..
if (ch == '\n' && newlines > 0) if (ch == '\n' && newlines > 0)
{ {
code << std::string(newlines, '\n'); code << std::string(newlines, '\n');
newlines = 0; newlines = 0;
previous = '\n';
} }
} }
} }

View File

@ -417,6 +417,23 @@ private:
ASSERT_EQUALS("\n\n\n\n", actual[""]); ASSERT_EQUALS("\n\n\n\n", actual[""]);
ASSERT_EQUALS(1, static_cast<unsigned int>(actual.size())); 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()));
}
} }