@@ -177,6 +177,8 @@ static bool handleIPrefix(yyscan_t yyscanner,const QCString &, const StringVecto
177
177
178
178
[[maybe_unused]] static const char *stateToString (int state);
179
179
180
+ static QCString fileInfoVal (QCString name, FileInfo fi);
181
+
180
182
typedef bool (*DocCmdFunc)(yyscan_t yyscanner,const QCString &name, const StringVector &optList);
181
183
typedef EntryType (*MakeEntryType)();
182
184
@@ -1918,25 +1920,90 @@ STopt [^\n@\\]*
1918
1920
1919
1921
/* ----- handle arguments of the section/subsection/.. commands ------- */
1920
1922
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;
1926
1925
}
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,
1929
1978
" \\section command has no label"
1930
1979
);
1980
+ }
1981
+ else
1982
+ {
1983
+ yyextra->sectionLabel=yyextra->raisePrefix+yyextra->sectionLabel;
1984
+ addOutput(yyscanner,yyextra->sectionLabel.data());
1985
+ addSection(yyscanner);
1986
+ }
1931
1987
if (*yytext=='\n ') yyextra->lineNr++;
1932
1988
addOutput(yyscanner,'\n ');
1933
1989
BEGIN( Comment );
1934
1990
}
1935
1991
<SectionLabel>. { // invalid character for section label
1936
- warn(yyextra->fileName,yyextra->lineNr,
1992
+ if (yyextra->sectionLabel.isEmpty())
1993
+ {
1994
+ warn(yyextra->fileName,yyextra->lineNr,
1937
1995
" Invalid or missing section label"
1938
1996
);
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
+ }
1940
2007
}
1941
2008
<SectionTitle>{STAopt}/" \n" { // end of section title
1942
2009
addSection(yyscanner);
@@ -3292,6 +3359,7 @@ static bool handleSection(yyscan_t yyscanner,const QCString &s, const StringVect
3292
3359
setOutput(yyscanner,OutputDoc);
3293
3360
// printf("handleSection(%s) raiseLevel=%d\n",qPrint(s),yyextra->raiseLevel);
3294
3361
BEGIN(SectionLabel);
3362
+ yyextra->sectionLabel.clear();
3295
3363
// determine natural section level
3296
3364
if (s==" section" ) yyextra->sectionLevel=SectionType::Section;
3297
3365
else if (s==" subsection" ) yyextra->sectionLevel=SectionType::Subsection;
@@ -3436,48 +3504,19 @@ static bool handleFileInfoSection(yyscan_t yyscanner,const QCString &cmdName, co
3436
3504
{
3437
3505
return handleFileInfoResult(yyscanner,cmdName, optList, true );
3438
3506
}
3439
- static bool handleFileInfoResult (yyscan_t yyscanner,const QCString &, const StringVector &optList, bool isSection)
3507
+
3508
+ static QCString fileInfoVal (QCString name, FileInfo fi)
3440
3509
{
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
+ }
3480
3517
3518
+ static bool handleFileInfoResult (yyscan_t yyscanner,const QCString &, const StringVector &optList, bool isSection)
3519
+ {
3481
3520
struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
3482
3521
if (!yyextra->spaceBeforeCmd.isEmpty())
3483
3522
{
@@ -3491,16 +3530,20 @@ static bool handleFileInfoResult(yyscan_t yyscanner,const QCString &, const Stri
3491
3530
{
3492
3531
QCString optStripped = QCString (opt_).stripWhiteSpace ();
3493
3532
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 ())
3496
3535
{
3497
3536
if (!first)
3498
3537
{
3499
3538
warn (yyextra->fileName ,yyextra->lineNr ," Multiple options specified with \\ fileinfo, discarding '{}'" , optStripped);
3500
3539
}
3501
3540
else
3502
3541
{
3503
- it->second (yyscanner,fi,isSection);
3542
+ addOutput (yyscanner,result);
3543
+ if (isSection)
3544
+ {
3545
+ yyextra->sectionTitle +=result;
3546
+ }
3504
3547
}
3505
3548
first = false ;
3506
3549
}
0 commit comments