Fix #1595 (case marks improperly tokenized with macro)

http://sourceforge.net/apps/trac/cppcheck/ticket/1595
This commit is contained in:
Reijo Tomperi 2010-04-15 23:21:00 +03:00
parent c718a7c595
commit 15e4b8dbd5
2 changed files with 54 additions and 1 deletions

View File

@ -1686,6 +1686,8 @@ public:
optcomma = false; optcomma = false;
macrocode += str; macrocode += str;
if (Token::Match(tok, "%var% %var%") || if (Token::Match(tok, "%var% %var%") ||
Token::Match(tok, "%var% %num%") ||
Token::Match(tok, "%num% %var%") ||
Token::Match(tok, "> >")) Token::Match(tok, "> >"))
macrocode += " "; macrocode += " ";
} }
@ -2075,7 +2077,7 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file
} }
// make sure number of newlines remain the same.. // make sure number of newlines remain the same..
const std::string macrocode(std::string(numberOfNewlines, '\n') + tempMacro); std::string macrocode(std::string(numberOfNewlines, '\n') + tempMacro);
// Insert macro code.. // Insert macro code..
if (macro->variadic() || macro->nopar() || !macro->params().empty()) if (macro->variadic() || macro->nopar() || !macro->params().empty())
@ -2102,6 +2104,10 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file
// erase macro // erase macro
line.erase(pos1, pos2 - pos1); line.erase(pos1, pos2 - pos1);
// Don't glue this macro into variable or number after it
if (std::isalnum(line[pos1]) || line[pos1] == '_')
macrocode.append(1,' ');
// insert expanded macro code // insert expanded macro code
line.insert(pos1, macrocode); line.insert(pos1, macrocode);

View File

@ -139,6 +139,7 @@ private:
TEST_CASE(macro_mismatch); TEST_CASE(macro_mismatch);
TEST_CASE(macro_linenumbers); TEST_CASE(macro_linenumbers);
TEST_CASE(macro_nopar); TEST_CASE(macro_nopar);
TEST_CASE(macro_switchCase);
TEST_CASE(string1); TEST_CASE(string1);
TEST_CASE(string2); TEST_CASE(string2);
TEST_CASE(string3); TEST_CASE(string3);
@ -1420,6 +1421,52 @@ private:
ASSERT_EQUALS("\n{ NULL }\n", OurPreprocessor::expandMacros(filedata)); ASSERT_EQUALS("\n{ NULL }\n", OurPreprocessor::expandMacros(filedata));
} }
void macro_switchCase()
{
{
// Make sure "case 2" doesn't become "case2"
const char filedata[] = "#define A( b ) "
"switch( a ){ "
"case 2: "
" break; "
"}\n"
"A( 5 );\n";
ASSERT_EQUALS("\nswitch(a){case 2:break;};\n", OurPreprocessor::expandMacros(filedata));
}
{
// Make sure "2 BB" doesn't become "2BB"
const char filedata[] = "#define A() AA : 2 BB\n"
"A();\n";
ASSERT_EQUALS("\nAA : 2 BB;\n", OurPreprocessor::expandMacros(filedata));
}
{
const char filedata[] = "#define A }\n"
"#define B() A\n"
"#define C( a ) B() break;\n"
"{C( 2 );\n";
ASSERT_EQUALS("\n\n\n{} break;;\n", OurPreprocessor::expandMacros(filedata));
}
{
const char filedata[] = "#define A }\n"
"#define B() A\n"
"#define C( a ) B() _break;\n"
"{C( 2 );\n";
ASSERT_EQUALS("\n\n\n{} _break;;\n", OurPreprocessor::expandMacros(filedata));
}
{
const char filedata[] = "#define A }\n"
"#define B() A\n"
"#define C( a ) B() 5;\n"
"{C( 2 );\n";
ASSERT_EQUALS("\n\n\n{} 5;;\n", OurPreprocessor::expandMacros(filedata));
}
}
void string1() void string1()
{ {