Fixed #3531 (When macro definition contains parenthesis, the #defined symbol does not get #defined.)

This commit is contained in:
Ahti Legonkov 2012-01-21 12:51:54 +01:00 committed by Daniel Marjamäki
parent 96ae010e48
commit 78461093f0
2 changed files with 58 additions and 14 deletions

View File

@ -1767,21 +1767,33 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str
suppressCurrentCodePath = false;
}
} else if (indentmatch == indent) {
if (!suppressCurrentCodePath && line.compare(0,8,"#define ")==0) {
// no value
std::string tag = line.substr(8);
if (line.find_first_of("( ", 8) == std::string::npos)
defs[tag] = "";
if (!suppressCurrentCodePath && line.compare(0, 8, "#define ") == 0) {
const unsigned int endOfDefine = 8;
std::string::size_type endOfTag = line.find_first_of("( ", endOfDefine);
std::string tag;
// define value
else if (line.find("(") == std::string::npos) {
const std::string::size_type pos = line.find(" ", 8);
tag = line.substr(8,pos-8);
const std::string value(line.substr(pos+1));
if (defs.find(value) != defs.end())
defs[tag] = defs[value];
else
defs[tag] = value;
// define a symbol
if (endOfTag == std::string::npos) {
tag = line.substr(endOfDefine);
defs[tag] = "";
} else {
tag = line.substr(endOfDefine, endOfTag-endOfDefine);
// define a function-macro
if (line[endOfTag] == '(') {
defs[tag] = "";
}
// define value
else {
++endOfTag;
const std::string& value = line.substr(endOfTag, line.size()-endOfTag);
if (defs.find(value) != defs.end())
defs[tag] = defs[value];
else
defs[tag] = value;
}
}
if (undefs.find(tag) != undefs.end()) {

View File

@ -236,6 +236,8 @@ private:
TEST_CASE(def_missingInclude);
TEST_CASE(def_handleIncludes_ifelse); // problems in handleIncludes for #else
TEST_CASE(def_valueWithParenthesis); // #3531
// Using -U to undefine symbols
TEST_CASE(undef1);
TEST_CASE(undef2);
@ -3109,6 +3111,36 @@ private:
}
}
void def_valueWithParenthesis() {
// #define should introduce a new symbol regardless of parenthesis in the value
// and regardless of white space in weird places (people do this for some reason).
const char code[] = "#define A (Fred)\n"
" # define B (Flintstone)\n"
" #define C (Barney)\n"
"\t#\tdefine\tD\t(Rubble)\t\t\t\n";
const std::string filePath("test.c");
const std::list<std::string> includePaths;
std::map<std::string,std::string> defs;
Preprocessor preprocessor(NULL, this);
std::istringstream istr(code);
const std::string s(preprocessor.read(istr, ""));
preprocessor.handleIncludes(s, filePath, includePaths, defs);
ASSERT(defs.find("A") != defs.end());
ASSERT_EQUALS("(Fred)", defs["A"]);
ASSERT(defs.find("B") != defs.end());
ASSERT_EQUALS("(Flintstone)", defs["B"]);
ASSERT(defs.find("C") != defs.end());
ASSERT_EQUALS("(Barney)", defs["C"]);
ASSERT(defs.find("D") != defs.end());
ASSERT_EQUALS("(Rubble)", defs["D"]);
}
void undef1() {
Settings settings;