@@ -1871,6 +1871,10 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
18711871<RemoveCPPComment>{CPPC}
18721872<RemoveCPPComment>[^\x06\n]+
18731873<RemoveCPPComment>.
1874+ <DefineText>" #" /" __VA_OPT__" {
1875+ yyextra->defText +=yytext;
1876+ yyextra->defLitText +=yytext;
1877+ }
18741878<DefineText>" #" /{IDSTART} {
18751879 outputChar (yyscanner,' ' );
18761880 yyextra->quoteArg =TRUE ;
@@ -2637,13 +2641,23 @@ static void skipCommentMacroName(yyscan_t yyscanner, const QCString &expr, QCStr
26372641// Expand C++20' s __VA_OPT__ (x) to either x if hasOptionalArgs==true or to the empty string if false
26382642static QCString expandVAOpt (const QCString &vaStr,bool hasOptionalArgs)
26392643{
2644+ // printf("expandVAOpt(vaStr=%s,hasOptionalArgs=%d)\n",qPrint(vaStr),hasOptionalArgs);
26402645 QCString result;
26412646 int vo=0 , vp=0 ;
26422647 result.clear();
26432648 int vl = static_cast <int >(vaStr.length());
26442649 while ((vo = vaStr.find(" __VA_OPT__(" ,vp))!=-1 )
26452650 {
2646- result+=vaStr.left (vo);
2651+ bool hasHash = vo>0 && vaStr.at (vo-1 )==' #' ;
2652+ if (hasHash)
2653+ {
2654+ result+=vaStr.mid (vp,vo-vp-1 ); // don't copy #
2655+ result+=" \" " ;
2656+ }
2657+ else
2658+ {
2659+ result+=vaStr.mid (vp,vo-vp);
2660+ }
26472661 int ve=vo+11 ; // skip over '__VA_OPT__(' part
26482662 int bc=1 ;
26492663 while (bc>0 && ve<vl)
@@ -2659,6 +2673,10 @@ static QCString expandVAOpt(const QCString &vaStr,bool hasOptionalArgs)
26592673 // printf("vo=%d ve=%d voStr=%s\n",vo,ve,qPrint(voStr));
26602674 result+=voStr; // take 'x' from __VA_OPT__(x)
26612675 }
2676+ if (hasHash)
2677+ {
2678+ result+=" \" " ;
2679+ }
26622680 vp=ve;
26632681 }
26642682 result+=vaStr.mid(vp);
@@ -2675,8 +2693,7 @@ static QCString expandVAOpt(const QCString &vaStr,bool hasOptionalArgs)
26752693 */
26762694static bool replaceFunctionMacro (yyscan_t yyscanner,const QCString &expr,QCString *rest,int pos,int &len,const Define *def,QCString &result,int level)
26772695{
2678- // YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
2679- // 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());
2696+ // printf(">replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s') level=%zu\n",qPrint(expr),rest ? qPrint(*rest) : 0,pos,qPrint(def->name),preYYget_extra(yyscanner)->levelGuard.size());
26802697 uint32_t j=pos;
26812698 len=0 ;
26822699 result.clear();
@@ -2697,6 +2714,7 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
26972714 std::map<std::string,std::string> argTable; // list of arguments
26982715 QCString arg;
26992716 int argCount=0 ;
2717+ int argCountNonEmpty=0 ;
27002718 bool done=FALSE ;
27012719
27022720 // PHASE 1: read the macro arguments
@@ -2750,14 +2768,17 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
27502768 {
27512769 if (c==' ,' && argCount==def->nargs -1 && def->varArgs )
27522770 {
2771+ expandExpression (yyscanner,arg,nullptr ,0 ,level+1 );
27532772 arg=arg.stripWhiteSpace ();
27542773 arg+=' ,' ;
27552774 }
27562775 else
27572776 {
2777+ expandExpression (yyscanner,arg,nullptr ,0 ,level+1 );
2778+ arg=arg.stripWhiteSpace ();
27582779 QCString argKey;
27592780 argKey.sprintf (" @%d" ,argCount++); // key name
2760- arg= arg.stripWhiteSpace () ;
2781+ if (c== ' , ' || ! arg.isEmpty ()) argCountNonEmpty++ ;
27612782 // add argument to the lookup table
27622783 argTable.emplace (toStdString (argKey), toStdString (arg));
27632784 arg.clear ();
@@ -2832,7 +2853,8 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
28322853 // substitution of all formal arguments
28332854 QCString resExpr;
28342855 QCString d=def->definition .stripWhiteSpace ();
2835- if (def->varArgs ) d = expandVAOpt (d,argCount!=def->nargs -1 );
2856+ // printf("varArgs=%d argCount=%d def->nargs=%d d=%s\n",def->varArgs,argCount,def->nargs,qPrint(d));
2857+ if (def->varArgs ) d = expandVAOpt (d,argCountNonEmpty!=def->nargs -1 );
28362858 // printf("Macro definition: '%s'\n",qPrint(d));
28372859 bool inString=FALSE ;
28382860 while (k<d.length ())
@@ -2915,10 +2937,10 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
29152937 }
29162938 len=j-pos;
29172939 result=resExpr;
2918- // printf("<replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s',result='%s') level=%zu return=TRUE\n",qPrint(expr),rest ? qPrint(*rest) : 0,pos,qPrint(def->name),qPrint(result),state ->levelGuard.size());
2940+ // printf("<replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s',result='%s') level=%zu return=TRUE\n",qPrint(expr),rest ? qPrint(*rest) : 0,pos,qPrint(def->name),qPrint(result),preYYget_extra(yyscanner) ->levelGuard.size());
29192941 return TRUE ;
29202942 }
2921- // printf("<replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s',result='%s') level=%zu return=FALSE\n",qPrint(expr),rest ? qPrint(*rest) : 0,pos,qPrint(def->name),qPrint(result),state ->levelGuard.size());
2943+ // printf("<replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s',result='%s') level=%zu return=FALSE\n",qPrint(expr),rest ? qPrint(*rest) : 0,pos,qPrint(def->name),qPrint(result),preYYget_extra(yyscanner) ->levelGuard.size());
29222944 return FALSE ;
29232945}
29242946
0 commit comments