diff --git a/simplecpp.cpp b/simplecpp.cpp index 9a9551c1..4740e7ec 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -570,10 +570,12 @@ void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filen currentToken += ch; } - if (currentToken == "<" && lastLine() == "# include") { - currentToken = readUntil(istr, location, '<', '>', outputList); - if (currentToken.size() < 2U) - return; + if (currentToken == "<") { + if ((lastLine() == "# include") || (lastLine() == (std::string("# define ") + lastTokenInLine()))) { + currentToken = readUntil(istr, location, '<', '>', outputList); + if (currentToken.size() < 2U) + return; + } } push_back(new Token(currentToken, location)); @@ -1015,6 +1017,19 @@ std::string simplecpp::TokenList::lastLine(int maxsize) const return ret; } +std::string simplecpp::TokenList::lastTokenInLine() const +{ + std::string ret; + for (const Token *tok = cback(); sameline(tok,cback()); tok = tok->previous) { + if (!tok->comment) { + ret = (tok->str[0] == '\"' ? std::string("%str%") + : std::isdigit(static_cast(tok->str[0])) ? std::string("%num%") : tok->str) + ret; + break; + } + } + return ret; +} + unsigned int simplecpp::TokenList::fileIndex(const std::string &filename) { for (unsigned int i = 0; i < files.size(); ++i) { diff --git a/simplecpp.h b/simplecpp.h index 19624e1d..10ca3fac 100755 --- a/simplecpp.h +++ b/simplecpp.h @@ -259,6 +259,7 @@ namespace simplecpp { std::string readUntil(std::istream &istr, const Location &location, const char start, const char end, OutputList *outputList); std::string lastLine(int maxsize=10) const; + std::string lastTokenInLine() const; unsigned int fileIndex(const std::string &filename); diff --git a/test.cpp b/test.cpp index 1a84e424..c85365e6 100644 --- a/test.cpp +++ b/test.cpp @@ -1055,6 +1055,28 @@ static void include6() // #57 - incomplete macro #include MACRO(,) simplecpp::preprocess(out, rawtokens, files, filedata, dui); } +static void include7() // #3 - handle #include MACRO with <> +{ + const char code_c[] = "#define A <3.h>\n#include A\n"; + const char code_h[] = "123\n"; + + std::vector files; + std::istringstream istr_c(code_c); + simplecpp::TokenList rawtokens_c(istr_c, files, "3.c"); + std::istringstream istr_h(code_h); + simplecpp::TokenList rawtokens_h(istr_h, files, "3.h"); + + std::map filedata; + filedata["3.c"] = &rawtokens_c; + filedata["3.h"] = &rawtokens_h; + + simplecpp::TokenList out(files); + simplecpp::DUI dui; + simplecpp::preprocess(out, rawtokens_c, files, filedata, dui); + + ASSERT_EQUALS("\n#line 1 \"3.h\"\n123", out.stringify()); +} + static void readfile_nullbyte() { const char code[] = "ab\0cd"; @@ -1445,6 +1467,7 @@ int main(int argc, char **argv) TEST_CASE(include4); // -include TEST_CASE(include5); // #include MACRO TEST_CASE(include6); // invalid code: #include MACRO(,) + TEST_CASE(include7); // #include MACRO with <> TEST_CASE(multiline1); TEST_CASE(multiline2);