@@ -342,6 +342,16 @@ static std::string escapeString(const std::string &str) {
342342 return ostr.str ();
343343}
344344
345+ static void portabilityBackslash (simplecpp::OutputList *outputList, const std::vector<std::string> &files, const simplecpp::Location &location) {
346+ if (!outputList)
347+ return ;
348+ simplecpp::Output err (files);
349+ err.type = simplecpp::Output::PORTABILITY_BACKSLASH;
350+ err.location = location;
351+ err.msg = " Combination 'backslash space newline' is not portable." ;
352+ outputList->push_back (err);
353+ }
354+
345355void simplecpp::TokenList::readfile (std::istream &istr, const std::string &filename, OutputList *outputList)
346356{
347357 std::stack<simplecpp::Location> loc;
@@ -363,6 +373,8 @@ void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filen
363373
364374 if (ch == ' \n ' ) {
365375 if (cback () && cback ()->op == ' \\ ' ) {
376+ if (location.col > cback ()->location .col + 1U )
377+ portabilityBackslash (outputList, files, cback ()->location );
366378 ++multiline;
367379 deleteToken (back ());
368380 } else {
@@ -415,6 +427,9 @@ void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filen
415427 currentToken += ch;
416428 ch = readChar (istr, bom);
417429 }
430+ const std::string::size_type pos = currentToken.find_last_not_of (" \t " );
431+ if (pos < currentToken.size () - 1U && currentToken[pos] == ' \\ ' )
432+ portabilityBackslash (outputList, files, location);
418433 if (currentToken[currentToken.size () - 1U ] == ' \\ ' ) {
419434 ++multiline;
420435 currentToken.erase (currentToken.size () - 1U );
@@ -1464,7 +1479,7 @@ class Macro {
14641479 Token *A = output->back ();
14651480 if (!A)
14661481 throw invalidHashHash (tok->location , name ());
1467- if (!sameline (tok, tok->next ))
1482+ if (!sameline (tok, tok->next ) || ! sameline (tok, tok-> next -> next ) )
14681483 throw invalidHashHash (tok->location , name ());
14691484
14701485 Token *B = tok->next ->next ;
@@ -1820,6 +1835,31 @@ std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::To
18201835 return ret;
18211836}
18221837
1838+ static bool preprocessToken (simplecpp::TokenList &output, const simplecpp::Token **tok1, std::map<std::string, simplecpp::Macro> ¯os, std::vector<std::string> &files, simplecpp::OutputList *outputList) {
1839+ const simplecpp::Token *tok = *tok1;
1840+ const std::map<std::string,simplecpp::Macro>::const_iterator it = macros.find (tok->str );
1841+ if (it != macros.end ()) {
1842+ simplecpp::TokenList value (files);
1843+ try {
1844+ *tok1 = it->second .expand (&value, tok, macros, files);
1845+ } catch (simplecpp::Macro::Error &err) {
1846+ simplecpp::Output out (files);
1847+ out.type = simplecpp::Output::SYNTAX_ERROR;
1848+ out.location = err.location ;
1849+ out.msg = " failed to expand \' " + tok->str + " \' , " + err.what ;
1850+ if (outputList)
1851+ outputList->push_back (out);
1852+ return false ;
1853+ }
1854+ output.takeTokens (value);
1855+ } else {
1856+ if (!tok->comment )
1857+ output.push_back (new simplecpp::Token (*tok));
1858+ *tok1 = tok->next ;
1859+ }
1860+ return true ;
1861+ }
1862+
18231863void simplecpp::preprocess (simplecpp::TokenList &output, const simplecpp::TokenList &rawtokens, std::vector<std::string> &files, const std::map<std::string, simplecpp::TokenList *> &filedata, const simplecpp::DUI &dui, simplecpp::OutputList *outputList, std::list<simplecpp::MacroUsage> *macroUsage)
18241864{
18251865 std::map<std::string, std::size_t > sizeOfType (rawtokens.sizeOfType );
@@ -1930,8 +1970,37 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
19301970 } catch (const std::runtime_error &) {
19311971 }
19321972 } else if (ifstates.top () == TRUE && rawtok->str == INCLUDE) {
1933- const bool systemheader = (rawtok->next ->str [0 ] == ' <' );
1934- const std::string header (realFilename (rawtok->next ->str .substr (1U , rawtok->next ->str .size () - 2U )));
1973+ TokenList inc1 (files);
1974+ for (const Token *inctok = rawtok->next ; sameline (rawtok,inctok); inctok = inctok->next ) {
1975+ if (!inctok->comment )
1976+ inc1.push_back (new Token (*inctok));
1977+ }
1978+ TokenList inc2 (files);
1979+ if (!inc1.empty () && inc1.cfront ()->name ) {
1980+ const Token *inctok = inc1.cfront ();
1981+ if (!preprocessToken (inc2, &inctok, macros, files, outputList)) {
1982+ output.clear ();
1983+ return ;
1984+ }
1985+ } else {
1986+ inc2.takeTokens (inc1);
1987+ }
1988+
1989+ if (inc2.empty ()) {
1990+ simplecpp::Output err (files);
1991+ err.type = Output::SYNTAX_ERROR;
1992+ err.location = rawtok->location ;
1993+ err.msg = " No header in #include" ;
1994+ if (outputList)
1995+ outputList->push_back (err);
1996+ output.clear ();
1997+ return ;
1998+ }
1999+
2000+ const Token *inctok = inc2.cfront ();
2001+
2002+ const bool systemheader = (inctok->op == ' <' );
2003+ const std::string header (realFilename (inctok->str .substr (1U , inctok->str .size () - 2U )));
19352004 const std::string header2 = getFileName (filedata, rawtok->location .file (), header, dui, systemheader);
19362005 if (header2.empty ()) {
19372006 simplecpp::Output output (files);
@@ -1996,24 +2065,10 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
19962065 continue ;
19972066 }
19982067
1999- const std::map<std::string,Macro>::const_iterator it = macros.find (tok->str );
2000- if (it != macros.end ()) {
2001- TokenList value (files);
2002- try {
2003- it->second .expand (&value, tok, macros, files);
2004- } catch (Macro::Error &err) {
2005- Output out (rawtok->location .files );
2006- out.type = Output::SYNTAX_ERROR;
2007- out.location = err.location ;
2008- out.msg = " failed to expand \' " + tok->str + " \' , " + err.what ;
2009- if (outputList)
2010- outputList->push_back (out);
2011- output.clear ();
2012- return ;
2013- }
2014- expr.takeTokens (value);
2015- } else {
2016- expr.push_back (new Token (*tok));
2068+ const Token *tmp = tok;
2069+ if (!preprocessToken (expr, &tmp, macros, files, outputList)) {
2070+ output.clear ();
2071+ return ;
20172072 }
20182073 }
20192074 try {
@@ -2081,28 +2136,9 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
20812136 const Location loc (rawtok->location );
20822137 TokenList tokens (files);
20832138
2084- if (macros.find (rawtok->str ) != macros.end ()) {
2085- std::map<TokenString,Macro>::const_iterator macro = macros.find (rawtok->str );
2086- if (macro != macros.end ()) {
2087- try {
2088- rawtok = macro->second .expand (&tokens, rawtok, macros, files);
2089- } catch (const simplecpp::Macro::Error &err) {
2090- Output out (err.location .files );
2091- out.type = Output::SYNTAX_ERROR;
2092- out.location = err.location ;
2093- out.msg = err.what ;
2094- if (outputList)
2095- outputList->push_back (out);
2096- output.clear ();
2097- return ;
2098- }
2099- }
2100- }
2101-
2102- else {
2103- if (!rawtok->comment )
2104- tokens.push_back (new Token (*rawtok));
2105- rawtok = rawtok->next ;
2139+ if (!preprocessToken (tokens, &rawtok, macros, files, outputList)) {
2140+ output.clear ();
2141+ return ;
21062142 }
21072143
21082144 if (hash || hashhash) {
0 commit comments