@@ -177,6 +177,8 @@ static bool handleIPrefix(yyscan_t yyscanner,const QCString &, const StringVecto
177177
178178[[maybe_unused]] static const char *stateToString (int state);
179179
180+ static QCString fileInfoVal (QCString name, FileInfo fi);
181+
180182typedef bool (*DocCmdFunc)(yyscan_t yyscanner,const QCString &name, const StringVector &optList);
181183typedef EntryType (*MakeEntryType)();
182184
@@ -1918,25 +1920,90 @@ STopt [^\n@\\]*
19181920
19191921 /* ----- handle arguments of the section/subsection/.. commands ------- */
19201922
1921- <SectionLabel>{LABELID} { // first argument
1922- yyextra->sectionLabel=yyextra->raisePrefix+yytext;
1923- addOutput(yyscanner,yyextra->sectionLabel.data());
1924- yyextra->sectionTitle.clear();
1925- BEGIN(SectionTitle);
1923+ <SectionLabel>{LABELID} {
1924+ yyextra->sectionLabel+=yytext;
19261925 }
1927- <SectionLabel>{DOCNL} { // missing argument
1928- warn(yyextra->fileName,yyextra->lineNr,
1926+ <SectionLabel>{CMD}" lineinfo" (" {}" )? {
1927+ yyextra->sectionLabel += QCString().setNum(yyextra->lineNr);
1928+ }
1929+ <SectionLabel>{CMD}" fileinfo" (" {" [^}]*" }" )? {
1930+ FileInfo fi(yyextra->fileName.str());
1931+ bool first = true;
1932+ if (yytext[9] == '{')
1933+ {
1934+ StringVector optList;
1935+ QCString txt = yytext;
1936+ QCString optStr = txt.mid(10,yyleng-11).stripWhiteSpace();
1937+ optList = split(optStr.str()," ," );
1938+ for (const auto &opt_ : optList)
1939+ {
1940+ QCString optStripped = QCString(opt_).stripWhiteSpace();
1941+ std::string opt = optStripped.lower().str();
1942+ QCString result = fileInfoVal(opt,fi);
1943+ if (!result.isEmpty())
1944+ {
1945+ if (!first)
1946+ {
1947+ warn(yyextra->fileName,yyextra->lineNr," Multiple options specified with \\fileinfo, discarding ' {}' " , optStripped);
1948+ }
1949+ else
1950+ {
1951+ yyextra->sectionLabel+=result;
1952+ }
1953+ first = false;
1954+ }
1955+ else
1956+ {
1957+ warn(yyextra->fileName,yyextra->lineNr," Unknown option specified with \\fileinfo: ' {}' " , optStripped);
1958+ }
1959+ }
1960+ }
1961+ if (first) // no options specified
1962+ {
1963+ if (Config_getBool(FULL_PATH_NAMES))
1964+ {
1965+ yyextra->sectionLabel+=stripFromPath(yyextra->fileName);
1966+ }
1967+ else
1968+ {
1969+ yyextra->sectionLabel+=yyextra->fileName;
1970+ }
1971+ }
1972+ }
1973+ <SectionLabel>{DOCNL} {
1974+ yyextra->sectionTitle.clear();
1975+ if (yyextra->sectionLabel.isEmpty())
1976+ { // missing argument
1977+ warn(yyextra->fileName,yyextra->lineNr,
19291978 " \\section command has no label"
19301979 );
1980+ }
1981+ else
1982+ {
1983+ yyextra->sectionLabel=yyextra->raisePrefix+yyextra->sectionLabel;
1984+ addOutput(yyscanner,yyextra->sectionLabel.data());
1985+ addSection(yyscanner);
1986+ }
19311987 if (*yytext=='\n ') yyextra->lineNr++;
19321988 addOutput(yyscanner,'\n ');
19331989 BEGIN( Comment );
19341990 }
19351991<SectionLabel>. { // invalid character for section label
1936- warn(yyextra->fileName,yyextra->lineNr,
1992+ if (yyextra->sectionLabel.isEmpty())
1993+ {
1994+ warn(yyextra->fileName,yyextra->lineNr,
19371995 " Invalid or missing section label"
19381996 );
1939- BEGIN(Comment);
1997+ BEGIN(Comment);
1998+ }
1999+ else
2000+ {
2001+ yyextra->sectionLabel=yyextra->raisePrefix+yyextra->sectionLabel;
2002+ addOutput(yyscanner,yyextra->sectionLabel.data());
2003+ yyextra->sectionTitle.clear();
2004+ unput_string(yytext,yyleng);
2005+ BEGIN(SectionTitle);
2006+ }
19402007 }
19412008<SectionTitle>{STAopt}/" \n" { // end of section title
19422009 addSection(yyscanner);
@@ -3292,6 +3359,7 @@ static bool handleSection(yyscan_t yyscanner,const QCString &s, const StringVect
32923359 setOutput(yyscanner,OutputDoc);
32933360 // printf("handleSection(%s) raiseLevel=%d\n",qPrint(s),yyextra->raiseLevel);
32943361 BEGIN(SectionLabel);
3362+ yyextra->sectionLabel.clear();
32953363 // determine natural section level
32963364 if (s==" section" ) yyextra->sectionLevel=SectionType::Section;
32973365 else if (s==" subsection" ) yyextra->sectionLevel=SectionType::Subsection;
@@ -3436,48 +3504,19 @@ static bool handleFileInfoSection(yyscan_t yyscanner,const QCString &cmdName, co
34363504{
34373505 return handleFileInfoResult(yyscanner,cmdName, optList, true );
34383506}
3439- static bool handleFileInfoResult (yyscan_t yyscanner,const QCString &, const StringVector &optList, bool isSection)
3507+
3508+ static QCString fileInfoVal (QCString name, FileInfo fi)
34403509{
3441- using OutputWriter = std::function<void (yyscan_t ,FileInfo &,bool )>;
3442- static std::unordered_map<std::string,OutputWriter> options =
3443- { // name, writer
3444- { " name" , [](yyscan_t s,FileInfo &fi,bool isSect) { addOutput (s,fi.baseName ());
3445- if (isSect)
3446- {
3447- struct yyguts_t *yyg = (struct yyguts_t *)s;
3448- yyextra->sectionTitle +=fi.baseName ();
3449- }
3450- } },
3451- { " extension" , [](yyscan_t s,FileInfo &fi,bool isSect) { addOutput (s,fi.extension (true ));
3452- if (isSect)
3453- {
3454- struct yyguts_t *yyg = (struct yyguts_t *)s;
3455- yyextra->sectionTitle +=fi.extension (true );
3456- }
3457- } },
3458- { " filename" , [](yyscan_t s,FileInfo &fi,bool isSect) { addOutput (s,fi.fileName ());
3459- if (isSect)
3460- {
3461- struct yyguts_t *yyg = (struct yyguts_t *)s;
3462- yyextra->sectionTitle +=fi.fileName ();
3463- }
3464- } },
3465- { " directory" , [](yyscan_t s,FileInfo &fi,bool isSect) { addOutput (s,fi.dirPath ());
3466- if (isSect)
3467- {
3468- struct yyguts_t *yyg = (struct yyguts_t *)s;
3469- yyextra->sectionTitle +=fi.dirPath ();
3470- }
3471- } },
3472- { " full" , [](yyscan_t s,FileInfo &fi,bool isSect) { addOutput (s,fi.absFilePath ());
3473- if (isSect)
3474- {
3475- struct yyguts_t *yyg = (struct yyguts_t *)s;
3476- yyextra->sectionTitle +=fi.absFilePath ();
3477- }
3478- } },
3479- };
3510+ if (name == " name" ) return fi.baseName();
3511+ if (name == " extension" ) return fi.extension(true );
3512+ if (name == " filename" ) return fi.fileName();
3513+ if (name == " directory" ) return fi.dirPath();
3514+ if (name == " full" ) return fi.absFilePath();
3515+ return " " ;
3516+ }
34803517
3518+ static bool handleFileInfoResult (yyscan_t yyscanner,const QCString &, const StringVector &optList, bool isSection)
3519+ {
34813520 struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
34823521 if (!yyextra->spaceBeforeCmd.isEmpty())
34833522 {
@@ -3491,16 +3530,20 @@ static bool handleFileInfoResult(yyscan_t yyscanner,const QCString &, const Stri
34913530 {
34923531 QCString optStripped = QCString (opt_).stripWhiteSpace ();
34933532 std::string opt = optStripped.lower ().str ();
3494- auto it = options. find (opt);
3495- if (it != options. end ())
3533+ QCString result = fileInfoVal (opt,fi );
3534+ if (!result. isEmpty ())
34963535 {
34973536 if (!first)
34983537 {
34993538 warn (yyextra->fileName ,yyextra->lineNr ," Multiple options specified with \\ fileinfo, discarding '{}'" , optStripped);
35003539 }
35013540 else
35023541 {
3503- it->second (yyscanner,fi,isSection);
3542+ addOutput (yyscanner,result);
3543+ if (isSection)
3544+ {
3545+ yyextra->sectionTitle +=result;
3546+ }
35043547 }
35053548 first = false ;
35063549 }
0 commit comments