Skip to content

Commit 4f36ca9

Browse files
committed
issue doxygen#11748 ALIASES expansion to form @section key causes : warning: Invalid section id ' '; ignoring section
Enabled possibility to have `@fileinfo` and `@lineinfo` in section labels.
1 parent 0829265 commit 4f36ca9

File tree

1 file changed

+95
-52
lines changed

1 file changed

+95
-52
lines changed

src/commentscan.l

Lines changed: 95 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
180182
typedef bool (*DocCmdFunc)(yyscan_t yyscanner,const QCString &name, const StringVector &optList);
181183
typedef 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

Comments
 (0)