Preprocessor: better handling of '#if A==1'

This commit is contained in:
Daniel Marjamäki 2012-02-29 19:08:01 +01:00
parent 527d3791e6
commit db1205cdb3
2 changed files with 58 additions and 0 deletions

View File

@ -1003,6 +1003,42 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const
if (! deflist.empty() && line.compare(0, 6, "#elif ") == 0) if (! deflist.empty() && line.compare(0, 6, "#elif ") == 0)
deflist.pop_back(); deflist.pop_back();
// translate A==1 condition to A=1 configuration
if (def.find("==") != std::string::npos) {
// Check if condition match pattern "%var% == %num%"
// %var%
std::string::size_type pos = 0;
if (std::isalpha(def[pos]) || def[pos] == '_') {
++pos;
while (std::isalnum(def[pos]) || def[pos] == '_')
++pos;
}
// ==
if (def.compare(pos,2,"==",0,2)==0)
pos += 2;
// %num%
if (pos<def.size() && std::isdigit(def[pos])) {
if (def.compare(pos,2,"0x",0,2)==0) {
pos += 2;
if (pos >= def.size())
pos = 0;
while (pos < def.size() && std::isxdigit(def[pos]))
++pos;
} else {
while (pos < def.size() && std::isdigit(def[pos]))
++pos;
}
// Does the condition match the pattern "%var% == %num%"?
if (pos == def.size()) {
def.erase(def.find("=="),1);
}
}
}
deflist.push_back(def); deflist.push_back(def);
def = ""; def = "";

View File

@ -76,6 +76,7 @@ private:
TEST_CASE(test7c); TEST_CASE(test7c);
TEST_CASE(test7d); TEST_CASE(test7d);
TEST_CASE(test7e); TEST_CASE(test7e);
TEST_CASE(test8); // #if A==1 => cfg: A=1
// #error => don't extract any code // #error => don't extract any code
TEST_CASE(error1); TEST_CASE(error1);
@ -617,6 +618,27 @@ private:
ASSERT_EQUALS(2, static_cast<unsigned int>(actual.size())); ASSERT_EQUALS(2, static_cast<unsigned int>(actual.size()));
} }
void test8() {
const char filedata[] = "#ifdef A == 1\n"
"1\n"
"#endif\n";
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Settings settings;
Preprocessor preprocessor(&settings, this);
errout.str("");
preprocessor.preprocess(istr, actual, "file.c");
// No error..
ASSERT_EQUALS("", errout.str());
// Compare results..
ASSERT_EQUALS(2U, actual.size());
ASSERT_EQUALS("\n\n\n", actual[""]);
ASSERT_EQUALS("\n1\n\n", actual["A=1"]);
}
void error1() { void error1() {
const char filedata[] = "#ifdef A\n" const char filedata[] = "#ifdef A\n"