@@ -2634,6 +2634,38 @@ static void skipCommentMacroName(yyscan_t yyscanner, const QCString &expr, QCStr
26342634 } while (changed);
26352635}
26362636
2637+ // Expand C++20' s __VA_OPT__ (x) to either x if hasOptionalArgs==true or to the empty string if false
2638+ static QCString expandVAOpt (const QCString &vaStr,bool hasOptionalArgs)
2639+ {
2640+ QCString result;
2641+ int vo=0 , vp=0 ;
2642+ result.clear();
2643+ int vl = static_cast <int >(vaStr.length());
2644+ while ((vo = vaStr.find(" __VA_OPT__(" ,vp))!=-1 )
2645+ {
2646+ result+=vaStr.left (vo);
2647+ int ve=vo+11 ; // skip over '__VA_OPT__(' part
2648+ int bc=1 ;
2649+ while (bc>0 && ve<vl)
2650+ {
2651+ if (vaStr[ve]==' )' ) bc--;
2652+ else if (vaStr[ve]==' (' ) bc++;
2653+ ve++;
2654+ }
2655+ // ve points to end of __VA_OPT__(....)
2656+ if (bc==0 && hasOptionalArgs)
2657+ {
2658+ QCString voStr = vaStr.mid (vo+11 ,ve-vo-12 );
2659+ // printf("vo=%d ve=%d voStr=%s\n",vo,ve,qPrint(voStr));
2660+ result+=voStr; // take 'x' from __VA_OPT__(x)
2661+ }
2662+ vp=ve;
2663+ }
2664+ result+=vaStr.mid(vp);
2665+ // printf("vaStr='%s'\n -> '%s'\n",qPrint(vaStr),qPrint(result));
2666+ return result;
2667+ }
2668+
26372669/ * ! replaces the function macro \a def whose argument list starts at
26382670 * \a pos in expression \a expr.
26392671 * Notice that this routine may scan beyond the \a expr string if needed.
@@ -2643,6 +2675,7 @@ static void skipCommentMacroName(yyscan_t yyscanner, const QCString &expr, QCStr
26432675 */
26442676static bool replaceFunctionMacro (yyscan_t yyscanner,const QCString &expr,QCString *rest,int pos,int &len,const Define *def,QCString &result,int level)
26452677{
2678+ // YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
26462679 // printf(">replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s') level=%zu\n",qPrint(expr),rest ? qPrint(*rest) : 0,pos,qPrint(def->name),state->levelGuard.size());
26472680 uint32_t j=pos;
26482681 len=0 ;
@@ -2678,7 +2711,7 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
26782711 else
26792712 {
26802713 while (!done && (argCount<def->nargs || def->varArgs ) &&
2681- ((cc=getNextChar (yyscanner,expr,rest,j))!=EOF && cc!=0 )
2714+ ((cc=getNextChar (yyscanner,expr,rest,j))!=EOF && cc!=0 )
26822715 )
26832716 {
26842717 char c=(char )cc;
@@ -2708,7 +2741,9 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
27082741 arg+=c;
27092742 }
27102743 else
2744+ {
27112745 arg+=c;
2746+ }
27122747 }
27132748 }
27142749 else if (c==' )' || c==' ,' ) // last or next argument found
@@ -2796,7 +2831,8 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
27962831 uint32_t k=0 ;
27972832 // substitution of all formal arguments
27982833 QCString resExpr;
2799- const QCString d=def->definition .stripWhiteSpace ();
2834+ QCString d=def->definition .stripWhiteSpace ();
2835+ if (def->varArgs ) d = expandVAOpt (d,argCount!=def->nargs -1 );
28002836 // printf("Macro definition: '%s'\n",qPrint(d));
28012837 bool inString=FALSE ;
28022838 while (k<d.length ())
@@ -3047,29 +3083,6 @@ static bool expandExpression(yyscan_t yyscanner,QCString &expr,QCString *rest,in
30473083 // printf(" <<<< call replaceFunctionMacro: replaced=%d\n",replaced);
30483084 len+=l;
30493085 }
3050- else if (macroName==" __VA_OPT__" )
3051- {
3052- // expr='( something __VA_OPT__(value) )' or '( something __VA_OPT__(value) something_else )'
3053- static const reg::Ex re (R"( __VA_OPT__\((.*)\)(.*)\))" );
3054- reg::Match m;
3055- std::string s = expr.mid (p).str ();
3056- if (reg::search (s,m,re))
3057- {
3058- assert (m.size ()==3 );
3059- std::string value = m[1 ].str ();
3060- std::string remainder = m[2 ].str ();
3061- // printf("value='%s' remainder='%s'\n",qPrint(value),qPrint(remainder));
3062- expMacro = stripWhiteSpace (remainder).empty () ? std::string () : value;
3063- expanded=true ;
3064- replaced=true ;
3065- len+=l+2 +m[1 ].str ().length ();
3066- }
3067- else
3068- {
3069- // printf("no match for '%s'\n",qPrint(expr));
3070- }
3071- }
3072- // printf(" macroName='%s' expMacro='%s' replaced=%d expanded=%d\n",qPrint(macroName),qPrint(expMacro),replaced,expanded);
30733086
30743087 if (replaced) // expand the macro and rescan the expression
30753088 {
0 commit comments