@@ -379,6 +379,7 @@ struct preYY_state
379
379
bool ccomment;
380
380
QCString delimiter;
381
381
QDict<void > allIncludes;
382
+ QDict<void > expansionDict;
382
383
DefineManager defineManager;
383
384
ConstExpressionParser constExpParser;
384
385
};
@@ -1933,7 +1934,7 @@ static QCString extractTrailingComment(const char *s)
1933
1934
static int getNextChar (yyscan_t yyscanner,const QCString &expr,QCString *rest,uint &pos);
1934
1935
static int getCurrentChar (yyscan_t yyscanner,const QCString &expr,QCString *rest,uint pos);
1935
1936
static void unputChar (yyscan_t yyscanner,const QCString &expr,QCString *rest,uint &pos,char c);
1936
- static void expandExpression (yyscan_t yyscanner,QCString &expr,QCString *rest,int pos);
1937
+ static void expandExpression (yyscan_t yyscanner,QCString &expr,QCString *rest,int pos, int level );
1937
1938
1938
1939
static QCString stringize (const QCString &s)
1939
1940
{
@@ -2068,10 +2069,10 @@ static inline void addTillEndOfString(yyscan_t yyscanner,const QCString &expr,QC
2068
2069
* The replacement string will be returned in \a result and the
2069
2070
* length of the (unexpanded) argument list is stored in \a len.
2070
2071
*/
2071
- static bool replaceFunctionMacro (yyscan_t yyscanner,const QCString &expr,QCString *rest,int pos,int &len,const Define *def,QCString &result)
2072
+ static bool replaceFunctionMacro (yyscan_t yyscanner,const QCString &expr,QCString *rest,int pos,int &len,const Define *def,QCString &result, int level )
2072
2073
{
2073
2074
YY_EXTRA_TYPE state = preYYget_extra (yyscanner);
2074
- // printf("replaceFunctionMacro(expr=%s ,rest=%s ,pos=%d,def=%s ) level=%d\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),state->level);
2075
+ // printf("> replaceFunctionMacro(expr='%s' ,rest='%s' ,pos=%d,def='%s' ) level=%d\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),state->level);
2075
2076
uint j=pos;
2076
2077
len=0 ;
2077
2078
result.resize (0 );
@@ -2225,7 +2226,7 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
2225
2226
// substitution of all formal arguments
2226
2227
QCString resExpr;
2227
2228
const QCString d=def->definition .stripWhiteSpace ();
2228
- // printf("Macro definition: %s \n",d.data());
2229
+ // printf("Macro definition: '%s' \n",d.data());
2229
2230
bool inString=FALSE ;
2230
2231
while (k<d.length ())
2231
2232
{
@@ -2269,7 +2270,10 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
2269
2270
// printf("substArg='%s'\n",substArg.data());
2270
2271
// only if no ## operator is before or after the argument
2271
2272
// marker we do macro expansion.
2272
- if (!hash) expandExpression (yyscanner,substArg,0 ,0 );
2273
+ if (!hash)
2274
+ {
2275
+ expandExpression (yyscanner,substArg,0 ,0 ,level+1 );
2276
+ }
2273
2277
if (inString)
2274
2278
{
2275
2279
// printf("'%s'=stringize('%s')\n",stringize(*subst).data(),subst->data());
@@ -2311,10 +2315,10 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
2311
2315
}
2312
2316
len=j-pos;
2313
2317
result=resExpr;
2314
- // printf("result after substitution '%s' expr='%s'\n",
2315
- // result.data(),expr.mid(pos,len).data());
2318
+ // printf("<replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s',result='%s') level=%d return=TRUE\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),result.data(),state->level);
2316
2319
return TRUE ;
2317
2320
}
2321
+ // printf("<replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s',result='%s') level=%d return=FALSE\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),result.data(),state->level);
2318
2322
return FALSE ;
2319
2323
}
2320
2324
@@ -2380,13 +2384,19 @@ static int getNextId(const QCString &expr,int p,int *l)
2380
2384
/*! performs recursive macro expansion on the string \a expr
2381
2385
* starting at position \a pos.
2382
2386
* May read additional characters from the input while re-scanning!
2383
- * If \a expandAll is \c TRUE then all macros in the expression are
2384
- * expanded, otherwise only the first is expanded.
2385
2387
*/
2386
- static void expandExpression (yyscan_t yyscanner,QCString &expr,QCString *rest,int pos)
2388
+ static void expandExpression (yyscan_t yyscanner,QCString &expr,QCString *rest,int pos, int level )
2387
2389
{
2388
2390
YY_EXTRA_TYPE state = preYYget_extra (yyscanner);
2389
- // printf("expandExpression(%s,%s)\n",expr.data(),rest ? rest->data() : 0);
2391
+ printf (" >expandExpression(expr='%s',rest='%s',pos=%d,level=%d)\n " ,expr.data (),rest ? rest->data () : 0 , pos, level);
2392
+ if (state->expansionDict .find (expr)!=0 ) // check for recursive expansions
2393
+ {
2394
+ return ;
2395
+ }
2396
+ else
2397
+ {
2398
+ state->expansionDict .insert (expr,(void *)0x8 );
2399
+ }
2390
2400
QCString macroName;
2391
2401
QCString expMacro;
2392
2402
bool definedTest=FALSE ;
@@ -2395,7 +2405,7 @@ static void expandExpression(yyscan_t yyscanner,QCString &expr,QCString *rest,in
2395
2405
{
2396
2406
bool replaced=FALSE ;
2397
2407
macroName=expr.mid (p,l);
2398
- // printf("macroName=%s\n",macroName.data());
2408
+ // printf(" p=%d macroName=%s\n",p ,macroName.data());
2399
2409
if (p<2 || !(expr.at (p-2 )==' @' && expr.at (p-1 )==' -' )) // no-rescan marker?
2400
2410
{
2401
2411
if (state->expandedDict ->find (macroName)==0 ) // expand macro
@@ -2432,29 +2442,33 @@ static void expandExpression(yyscan_t yyscanner,QCString &expr,QCString *rest,in
2432
2442
}
2433
2443
else if (def && def->nargs >=0 ) // function macro
2434
2444
{
2435
- replaced=replaceFunctionMacro (yyscanner,expr,rest,p+l,len,def,expMacro);
2445
+ // printf(" >>>> call replaceFunctionMacro\n");
2446
+ replaced=replaceFunctionMacro (yyscanner,expr,rest,p+l,len,def,expMacro,level);
2447
+ // printf(" <<<< call replaceFunctionMacro: replaced=%d\n",replaced);
2436
2448
len+=l;
2437
2449
}
2450
+ // printf(" macroName='%s' expMacro='%s' replaced=%d\n",macroName.data(),expMacro.data(),replaced);
2438
2451
2439
2452
if (replaced) // expand the macro and rescan the expression
2440
2453
{
2441
- // printf("replacing '%s'->'%s'\n",expr.mid(p,len).data(),expMacro.data());
2454
+ // printf(" replacing '%s'->'%s'\n",expr.mid(p,len).data(),expMacro.data());
2442
2455
QCString resultExpr=expMacro;
2443
2456
QCString restExpr=expr.right (expr.length ()-len-p);
2444
2457
processConcatOperators (resultExpr);
2458
+ // printf(" macroName=%s def->nonRecursive=%d\n",macroName.data(),def->nonRecursive);
2445
2459
if (def && !def->nonRecursive )
2446
2460
{
2447
2461
state->expandedDict ->insert (macroName,def);
2448
- expandExpression (yyscanner,resultExpr,&restExpr,0 );
2462
+ expandExpression (yyscanner,resultExpr,&restExpr,0 ,level+ 1 );
2449
2463
state->expandedDict ->remove (macroName);
2450
2464
}
2451
2465
expr=expr.left (p)+resultExpr+restExpr;
2466
+ // printf(" new expression: '%s' old i=%d new i=%d\n",expr.data(),i,p);
2452
2467
i=p;
2453
- // printf("new expression: %s\n",expr.data());
2454
2468
}
2455
2469
else // move to the next macro name
2456
2470
{
2457
- // printf("moving to the next macro old=%d new=%d\n",i,p+l);
2471
+ // printf(" moving to the next macro old i =%d new i =%d\n",i,p+l);
2458
2472
i=p+l;
2459
2473
}
2460
2474
}
@@ -2472,6 +2486,7 @@ static void expandExpression(yyscan_t yyscanner,QCString &expr,QCString *rest,in
2472
2486
i=p+l;
2473
2487
}
2474
2488
}
2489
+ printf (" <expandExpression(expr='%s',rest='%s',pos=%d,level=%d)\n " ,expr.data (),rest ? rest->data () : 0 , pos,level);
2475
2490
}
2476
2491
2477
2492
/*! @brief Process string or character literal.
@@ -2700,7 +2715,8 @@ static bool computeExpression(yyscan_t yyscanner,const QCString &expr)
2700
2715
{
2701
2716
YY_EXTRA_TYPE state = preYYget_extra (yyscanner);
2702
2717
QCString e=expr;
2703
- expandExpression (yyscanner,e,0 ,0 );
2718
+ state->expansionDict .clear ();
2719
+ expandExpression (yyscanner,e,0 ,0 ,0 );
2704
2720
// printf("after expansion '%s'\n",e.data());
2705
2721
e = removeIdsAndMarkers (e);
2706
2722
if (e.isEmpty ()) return FALSE ;
@@ -2714,8 +2730,10 @@ static bool computeExpression(yyscan_t yyscanner,const QCString &expr)
2714
2730
2715
2731
static QCString expandMacro (yyscan_t yyscanner,const QCString &name)
2716
2732
{
2733
+ YY_EXTRA_TYPE state = preYYget_extra (yyscanner);
2717
2734
QCString n=name;
2718
- expandExpression (yyscanner,n,0 ,0 );
2735
+ state->expansionDict .clear ();
2736
+ expandExpression (yyscanner,n,0 ,0 ,0 );
2719
2737
n=removeMarkers (n);
2720
2738
// printf("expandMacro '%s'->'%s'\n",name.data(),n.data());
2721
2739
return n;
@@ -2750,7 +2768,7 @@ static void addDefine(yyscan_t yyscanner)
2750
2768
// conditional section (cond command) that is disabled.
2751
2769
if (!Doxygen::gatherDefines) return ;
2752
2770
2753
- // printf("addDefine %s %s \n",state->defName.data(),state->defArgsStr.data());
2771
+ // printf("addDefine '%s' '%s' \n",state->defName.data(),state->defArgsStr.data());
2754
2772
// ArgumentList *al = new ArgumentList;
2755
2773
// stringToArgumentList(state->defArgsStr,al);
2756
2774
MemberDef *md=createMemberDef (
@@ -3180,6 +3198,11 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output
3180
3198
yyscan_t yyscanner = p->yyscanner ;
3181
3199
YY_EXTRA_TYPE state = preYYget_extra (p->yyscanner );
3182
3200
struct yyguts_t *yyg = (struct yyguts_t *)p->yyscanner ;
3201
+
3202
+ #ifdef FLEX_DEBUG
3203
+ preYYset_debug (1 ,yyscanner);
3204
+ #endif
3205
+
3183
3206
printlex (yy_flex_debug, TRUE , __FILE__, fileName);
3184
3207
uint orgOffset=output.curPos ();
3185
3208
// printf("##########################\n%s\n####################\n",
0 commit comments