@@ -110,6 +110,15 @@ template<class T> static std::string toString(T t)
110
110
return ostr.str ();
111
111
}
112
112
113
+ #ifdef SIMPLECPP_DEBUG_MACRO_EXPANSION
114
+ static std::string locstring (const simplecpp::Location &loc)
115
+ {
116
+ std::ostringstream ostr;
117
+ ostr << ' [' << loc.file () << ' :' << loc.line << ' :' << loc.col << ' ]' ;
118
+ return ostr.str ();
119
+ }
120
+ #endif
121
+
113
122
static long long stringToLL (const std::string &s)
114
123
{
115
124
long long ret;
@@ -1528,6 +1537,10 @@ namespace simplecpp {
1528
1537
std::vector<std::string> &inputFiles) const {
1529
1538
std::set<TokenString> expandedmacros;
1530
1539
1540
+ #ifdef SIMPLECPP_DEBUG_MACRO_EXPANSION
1541
+ std::cout << " expand " << name () << " " << locstring (rawtok->location ) << std::endl;
1542
+ #endif
1543
+
1531
1544
TokenList output2 (inputFiles);
1532
1545
1533
1546
if (functionLike () && rawtok->next && rawtok->next ->op == ' (' ) {
@@ -1797,6 +1810,10 @@ namespace simplecpp {
1797
1810
const Token * expand (TokenList * const output, const Location &loc, const Token * const nameTokInst, const MacroMap ¯os, std::set<TokenString> expandedmacros) const {
1798
1811
expandedmacros.insert (nameTokInst->str ());
1799
1812
1813
+ #ifdef SIMPLECPP_DEBUG_MACRO_EXPANSION
1814
+ std::cout << " expand " << name () << " " << locstring (defineLocation ()) << std::endl;
1815
+ #endif
1816
+
1800
1817
usageList.push_back (loc);
1801
1818
1802
1819
if (nameTokInst->str () == " __FILE__" ) {
@@ -2168,8 +2185,7 @@ namespace simplecpp {
2168
2185
2169
2186
const bool canBeConcatenatedWithEqual = A->isOneOf (" +-*/%&|^" ) || A->str () == " <<" || A->str () == " >>" ;
2170
2187
const bool canBeConcatenatedStringOrChar = isStringLiteral_ (A->str ()) || isCharLiteral_ (A->str ());
2171
- if (!A->name && !A->number && A->op != ' ,' && !A->str ().empty () && !canBeConcatenatedWithEqual && !canBeConcatenatedStringOrChar)
2172
- throw invalidHashHash::unexpectedToken (tok->location , name (), A);
2188
+ const bool unexpectedA = (!A->name && !A->number && !A->str ().empty () && !canBeConcatenatedWithEqual && !canBeConcatenatedStringOrChar);
2173
2189
2174
2190
Token * const B = tok->next ->next ;
2175
2191
if (!B->name && !B->number && B->op && !B->isOneOf (" #=" ))
@@ -2187,6 +2203,9 @@ namespace simplecpp {
2187
2203
const Token *nextTok = B->next ;
2188
2204
2189
2205
if (canBeConcatenatedStringOrChar) {
2206
+ if (unexpectedA)
2207
+ throw invalidHashHash::unexpectedToken (tok->location , name (), A);
2208
+
2190
2209
// It seems clearer to handle this case separately even though the code is similar-ish, but we don't want to merge here.
2191
2210
// TODO The question is whether the ## or varargs may still apply, and how to provoke?
2192
2211
if (expandArg (&tokensB, B, parametertokens)) {
@@ -2205,13 +2224,17 @@ namespace simplecpp {
2205
2224
if (expandArg (&tokensB, B, parametertokens)) {
2206
2225
if (tokensB.empty ())
2207
2226
strAB = A->str ();
2208
- else if (varargs && A->op == ' ,' ) {
2227
+ else if (varargs && A->op == ' ,' )
2209
2228
strAB = " ," ;
2210
- } else {
2229
+ else if (varargs && unexpectedA)
2230
+ throw invalidHashHash::unexpectedToken (tok->location , name (), A);
2231
+ else {
2211
2232
strAB = A->str () + tokensB.cfront ()->str ();
2212
2233
tokensB.deleteToken (tokensB.front ());
2213
2234
}
2214
2235
} else {
2236
+ if (unexpectedA)
2237
+ throw invalidHashHash::unexpectedToken (tok->location , name (), A);
2215
2238
strAB = A->str () + B->str ();
2216
2239
}
2217
2240
0 commit comments