Skip to content

Commit 84eda2f

Browse files
committed
Merge branch 'albert-github-feature/issue_11748'
2 parents a7ab804 + 6cd712a commit 84eda2f

File tree

2 files changed

+126
-52
lines changed

2 files changed

+126
-52
lines changed

src/commentscan.l

Lines changed: 126 additions & 51 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 fileInfoLookup(const FileInfo &fi,const std::string &name);
181+
180182
typedef bool (*DocCmdFunc)(yyscan_t yyscanner,const QCString &name, const StringVector &optList);
181183
typedef EntryType (*MakeEntryType)();
182184

@@ -554,6 +556,7 @@ static int yyread(yyscan_t yyscanner,char *buf,int max_size);
554556
static void addCite(yyscan_t yyscanner);
555557
static void addIline(yyscan_t yyscanner,int lineNr);
556558
static void addIlineBreak(yyscan_t yyscanner,int lineNr);
559+
static void escapeLabel(QCString &label);
557560

558561
#define unput_string(yytext,yyleng) do { for (int i=(int)yyleng-1;i>=0;i--) unput(yytext[i]); } while(0)
559562

@@ -1918,25 +1921,93 @@ STopt [^\n@\\]*
19181921
19191922
/* ----- handle arguments of the section/subsection/.. commands ------- */
19201923
1921-
<SectionLabel>{LABELID} { // first argument
1922-
yyextra->sectionLabel=yyextra->raisePrefix+yytext;
1923-
addOutput(yyscanner,yyextra->sectionLabel.data());
1924-
yyextra->sectionTitle.clear();
1925-
BEGIN(SectionTitle);
1924+
<SectionLabel>{LABELID} {
1925+
yyextra->sectionLabel+=yytext;
19261926
}
1927-
<SectionLabel>{DOCNL} { // missing argument
1928-
warn(yyextra->fileName,yyextra->lineNr,
1927+
<SectionLabel>{CMD}"lineinfo"("{}")? {
1928+
yyextra->sectionLabel += QCString().setNum(yyextra->lineNr);
1929+
}
1930+
<SectionLabel>{CMD}"fileinfo"("{"[^}]*"}")? {
1931+
FileInfo fi(yyextra->fileName.str());
1932+
bool hasOption = false;
1933+
QCString label;
1934+
if (yytext[yyleng-1] == '}') // has parameters
1935+
{
1936+
StringVector optList;
1937+
QCString txt = yytext;
1938+
QCString optStr = txt.mid(10,yyleng-11).stripWhiteSpace();
1939+
optList = split(optStr.str(),",");
1940+
for (const auto &opt_ : optList)
1941+
{
1942+
QCString optStripped = QCString(opt_).stripWhiteSpace();
1943+
std::string opt = optStripped.lower().str();
1944+
QCString result = fileInfoLookup(fi,opt);
1945+
if (!result.isEmpty())
1946+
{
1947+
if (hasOption) // oops: already found an option
1948+
{
1949+
warn(yyextra->fileName,yyextra->lineNr,"Multiple options specified with \\fileinfo, discarding '{}'", optStripped);
1950+
}
1951+
else
1952+
{
1953+
label = result;
1954+
}
1955+
hasOption = true;
1956+
}
1957+
else
1958+
{
1959+
warn(yyextra->fileName,yyextra->lineNr,"Unknown option specified with \\fileinfo: '{}'", optStripped);
1960+
}
1961+
}
1962+
}
1963+
if (!hasOption)
1964+
{
1965+
if (Config_getBool(FULL_PATH_NAMES))
1966+
{
1967+
label=stripFromPath(yyextra->fileName);
1968+
}
1969+
else
1970+
{
1971+
label=yyextra->fileName;
1972+
}
1973+
}
1974+
escapeLabel(label);
1975+
yyextra->sectionLabel+=label;
1976+
}
1977+
<SectionLabel>{DOCNL} {
1978+
yyextra->sectionTitle.clear();
1979+
if (yyextra->sectionLabel.isEmpty())
1980+
{ // missing argument
1981+
warn(yyextra->fileName,yyextra->lineNr,
19291982
"\\section command has no label"
19301983
);
1984+
}
1985+
else
1986+
{
1987+
yyextra->sectionLabel=yyextra->raisePrefix+yyextra->sectionLabel;
1988+
addOutput(yyscanner,yyextra->sectionLabel.data());
1989+
addSection(yyscanner);
1990+
}
19311991
if (*yytext=='\n') yyextra->lineNr++;
19321992
addOutput(yyscanner,'\n');
19331993
BEGIN( Comment );
19341994
}
19351995
<SectionLabel>. { // invalid character for section label
1936-
warn(yyextra->fileName,yyextra->lineNr,
1996+
if (yyextra->sectionLabel.isEmpty())
1997+
{
1998+
warn(yyextra->fileName,yyextra->lineNr,
19371999
"Invalid or missing section label"
19382000
);
1939-
BEGIN(Comment);
2001+
BEGIN(Comment);
2002+
}
2003+
else
2004+
{
2005+
yyextra->sectionLabel=yyextra->raisePrefix+yyextra->sectionLabel;
2006+
addOutput(yyscanner,yyextra->sectionLabel.data());
2007+
yyextra->sectionTitle.clear();
2008+
unput_string(yytext,yyleng);
2009+
BEGIN(SectionTitle);
2010+
}
19402011
}
19412012
<SectionTitle>{STAopt}/"\n" { // end of section title
19422013
addSection(yyscanner);
@@ -3292,6 +3363,7 @@ static bool handleSection(yyscan_t yyscanner,const QCString &s, const StringVect
32923363
setOutput(yyscanner,OutputDoc);
32933364
//printf("handleSection(%s) raiseLevel=%d\n",qPrint(s),yyextra->raiseLevel);
32943365
BEGIN(SectionLabel);
3366+
yyextra->sectionLabel.clear();
32953367
// determine natural section level
32963368
if (s=="section") yyextra->sectionLevel=SectionType::Section;
32973369
else if (s=="subsection") yyextra->sectionLevel=SectionType::Subsection;
@@ -3436,48 +3508,25 @@ static bool handleFileInfoSection(yyscan_t yyscanner,const QCString &cmdName, co
34363508
{
34373509
return handleFileInfoResult(yyscanner,cmdName, optList, true);
34383510
}
3439-
static bool handleFileInfoResult(yyscan_t yyscanner,const QCString &, const StringVector &optList, bool isSection)
3511+
3512+
static QCString fileInfoLookup(const FileInfo &fi,const std::string &optionName)
34403513
{
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-
} },
3514+
using OptionFunc = std::function<QCString(const FileInfo &)>;
3515+
static std::unordered_map<std::string,OptionFunc> options =
3516+
{
3517+
// name, function producing the value
3518+
{ "name", [](const FileInfo &fi_) { return fi_.baseName(); } },
3519+
{ "extension", [](const FileInfo &fi_) { return fi_.extension(true); } },
3520+
{ "filename", [](const FileInfo &fi_) { return fi_.fileName(); } },
3521+
{ "directory", [](const FileInfo &fi_) { return fi_.dirPath(); } },
3522+
{ "full", [](const FileInfo &fi_) { return fi_.absFilePath(); } }
34793523
};
3524+
auto it = options.find(optionName);
3525+
return (it!=options.end()) ? it->second(fi) : QCString();
3526+
}
34803527

3528+
static bool handleFileInfoResult(yyscan_t yyscanner,const QCString &, const StringVector &optList, bool isSection)
3529+
{
34813530
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
34823531
if (!yyextra->spaceBeforeCmd.isEmpty())
34833532
{
@@ -3491,16 +3540,20 @@ static bool handleFileInfoResult(yyscan_t yyscanner,const QCString &, const Stri
34913540
{
34923541
QCString optStripped = QCString(opt_).stripWhiteSpace();
34933542
std::string opt = optStripped.lower().str();
3494-
auto it = options.find(opt);
3495-
if (it != options.end())
3543+
QCString result = fileInfoLookup(fi,opt);
3544+
if (!result.isEmpty())
34963545
{
34973546
if (!first)
34983547
{
34993548
warn(yyextra->fileName,yyextra->lineNr,"Multiple options specified with \\fileinfo, discarding '{}'", optStripped);
35003549
}
35013550
else
35023551
{
3503-
it->second(yyscanner,fi,isSection);
3552+
addOutput(yyscanner,result);
3553+
if (isSection)
3554+
{
3555+
yyextra->sectionTitle+=result;
3556+
}
35043557
}
35053558
first = false;
35063559
}
@@ -4299,6 +4352,28 @@ static void addXRefItem(yyscan_t yyscanner,
42994352
yyextra->outputXRef.clear();
43004353
}
43014354

4355+
//-----------------------------------------------------------------------------
4356+
4357+
// make label match LABELID pattern
4358+
static void escapeLabel(QCString &label)
4359+
{
4360+
if (label.isEmpty()) return;
4361+
char c = label[0];
4362+
if (!((c>='a' && c<='z') || (c>='A' && c<='Z') || c=='_' || c<0))
4363+
{
4364+
label[0]='_'; // replace invalid starting char by _
4365+
}
4366+
for (size_t i=1; i<label.size(); i++)
4367+
{
4368+
c = label[i];
4369+
if (!((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_' || c<0))
4370+
{
4371+
label[i]='_'; // replace invalid char by _
4372+
}
4373+
}
4374+
}
4375+
4376+
43024377
//-----------------------------------------------------------------------------
43034378

43044379
// Adds a formula text to the list/dictionary of formulas if it was

src/util.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3248,7 +3248,6 @@ bool getCaseSenseNames()
32483248
else return Portable::fileSystemIsCaseSensitive();
32493249
}
32503250

3251-
// note that this function is not reentrant due to the use of static growBuf!
32523251
QCString escapeCharsInString(const QCString &name,bool allowDots,bool allowUnderscore)
32533252
{
32543253
if (name.isEmpty()) return name;

0 commit comments

Comments
 (0)