Skip to content

Commit 3c96f81

Browse files
committed
issue #10935 \snippet{doc} tag in Doxygen v1.11 adds incorrect paragraph with a break before snippet text
1 parent d51b6df commit 3c96f81

7 files changed

Lines changed: 63 additions & 31 deletions

File tree

src/commentcnv.l

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,15 +1314,16 @@ SLASHopt [/]*
13141314
yyextra->inBuf = fs->oldFileBuf;
13151315
yyextra->inBufPos = fs->oldFileBufPos;
13161316
yyextra->includeCtx = fs->oldIncludeCtx;
1317-
QCString lineStr= " \\ilinebr \\ifile \""+yyextra->fileName+"\" \\iline "+QCString().setNum(yyextra->lineNr)+" ";
1317+
QCString lineStr= " \\ifile \""+yyextra->fileName+"\" \\iline "+QCString().setNum(yyextra->lineNr)+" ";
13181318
if (fs->oldRaiseLvl!=yyextra->raiseLevel)
13191319
{
1320-
lineStr+=" \\iraise " + std::to_string(fs->oldRaiseLvl);
1320+
lineStr+="\\iraise " + std::to_string(fs->oldRaiseLvl)+ " ";
13211321
}
13221322
if (fs->oldRaiseLbl!=yyextra->raiseLabel)
13231323
{
1324-
lineStr+=" \\iprefix \"" + fs->oldRaiseLbl + "\"";
1324+
lineStr+="\\iprefix \"" + fs->oldRaiseLbl + "\" ";
13251325
}
1326+
lineStr+="\\ilinebr ";
13261327
yyextra->raiseLevel = fs->oldRaiseLvl;
13271328
yyextra->raiseLabel = fs->oldRaiseLbl;
13281329
copyToOutput(yyscanner,lineStr.view());
@@ -1719,24 +1720,21 @@ static bool readIncludeFile(yyscan_t yyscanner,const QCString &inc,const QCStrin
17191720
QCString oldRaiseLabel = yyextra->raiseLabel;
17201721
yyextra->raiseLevel+=yyextra->raiseIncrement;
17211722
yyextra->raiseLabel+=yyextra->raisePrefix;
1722-
lineNr--;
1723-
QCString lineStr=" \\ilinebr \\ifile \""+absFileName+"\" \\iline " + std::to_string(lineNr);
1723+
QCString lineStr=" \\ifile \""+absFileName+"\" \\iline " + std::to_string(lineNr)+" ";
17241724
if (yyextra->raiseLevel>0)
17251725
{
1726-
lineStr+=" \\iraise " + std::to_string(yyextra->raiseLevel);
1726+
lineStr+="\\iraise " + std::to_string(yyextra->raiseLevel)+" ";
17271727
}
17281728
if (!yyextra->raiseLabel.isEmpty())
17291729
{
1730-
lineStr+=" \\iprefix \"" + yyextra->raiseLabel + "\"";
1730+
lineStr+="\\iprefix \"" + yyextra->raiseLabel + "\" ";
17311731
}
1732-
copyToOutput(yyscanner,lineStr.view());
1733-
insertCommentStart(yyscanner);
1734-
lineStr="\n";
1732+
lineStr+="\\ilinebr ";
17351733
copyToOutput(yyscanner,lineStr.view());
17361734
17371735
fs->fileName = absFileName;
17381736
fs->bufState = YY_CURRENT_BUFFER;
1739-
fs->oldLineNr = yyextra->lineNr-1;
1737+
fs->oldLineNr = yyextra->lineNr;
17401738
fs->oldFileName = yyextra->fileName;
17411739
fs->oldState = yyextra->includeCtx;
17421740
fs->oldFileBuf = yyextra->inBuf;

src/commentscan.l

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ typedef yyguts_t *yyscan_t;
6565
#include "reflist.h"
6666
#include "trace.h"
6767
#include "debug.h"
68+
#include "stringutil.h"
6869

6970
// forward declarations
7071
static bool handleBrief(yyscan_t yyscanner,const QCString &, const StringVector &);
@@ -599,6 +600,7 @@ MAILADDR ("mailto:")?[a-z_A-Z0-9\x80-\xff.+-]+"@"[a-z_A-Z0-9\x80-\xff-]+("."[a-
599600
RCSTAG "$"{ID}":"[^\n$]+"$"
600601
MODULE_ID ({ID}".")*{ID}
601602
LINENR {Bopt}[1-9][0-9]*
603+
IFILELINE ("\\ifile \""[^"]*"\" \\iline "[0-9]+" "("iprefix \""[^"]*"\" ")?("iraise "[0-9]+" ")?)
602604

603605
// C start comment
604606
CCS "/\*"
@@ -899,6 +901,16 @@ STopt [^\n@\\]*
899901
<Comment>{B}*"\\ilinebr"{B}* { // preserve spacing around \\ilinebr
900902
addOutput(yyscanner,yytext);
901903
}
904+
<Comment>(\n|\\ilinebr)/({B}*(\n|{IFILELINE}?\\ilinebr))+ { // at least one blank line (or blank line command)
905+
if (yyextra->inContext==OutputBrief)
906+
{
907+
endBrief(yyscanner);
908+
}
909+
else
910+
{
911+
REJECT;
912+
}
913+
}
902914
<Comment>{B}*{CMD}[a-z_A-Z]+"{"[^}]*"}"{B}* |
903915
<Comment>{B}*{CMD}[a-z_A-Z]+{B}* { // potentially interesting command
904916
// the {B}* in the front was added for bug620924
@@ -1471,7 +1483,7 @@ STopt [^\n@\\]*
14711483
//if (*yytext=='\n') yyextra->lineNr++;
14721484
//addOutput(yyscanner,'\n');
14731485
addOutput(yyscanner," \\ifile \""+ yyextra->fileName);
1474-
addOutput(yyscanner,"\" \\ilinebr \\iline " + QCString().setNum(yyextra->lineNr + extraLineNr) + " \\ilinebr ");
1486+
addOutput(yyscanner,"\" \\iline " + QCString().setNum(yyextra->lineNr + extraLineNr) + " \\ilinebr ");
14751487
BEGIN( Comment );
14761488
}
14771489
<GroupDocArg2>. { // title (stored in type)
@@ -1524,7 +1536,7 @@ STopt [^\n@\\]*
15241536
//if (*yytext=='\n') yyextra->lineNr++;
15251537
//addOutput(yyscanner,'\n');
15261538
addOutput(yyscanner," \\ifile \""+ yyextra->fileName);
1527-
addOutput(yyscanner,"\" \\ilinebr \\iline " + QCString().setNum(yyextra->lineNr) + " \\ilinebr ");
1539+
addOutput(yyscanner,"\" \\iline " + QCString().setNum(yyextra->lineNr) + " \\ilinebr ");
15281540
BEGIN( Comment );
15291541
}
15301542
<PageDocArg2>{CMD}[<>] {
@@ -4253,6 +4265,7 @@ static void addCite(yyscan_t yyscanner)
42534265
}
42544266

42554267
//-----------------------------------------------------------------------------
4268+
static const reg::Ex nonBrief_re(R"( *[\\@]ifile \"[^\"]*\" [\\@]iline (\d+) [\\@]ilinebr( *\n*))");
42564269

42574270
// strip trailing whitespace (excluding newlines) from string s
42584271
static void stripTrailingWhiteSpace(QCString &s)
@@ -4390,15 +4403,14 @@ static inline void setOutput(yyscan_t yyscanner,OutputContext ctx)
43904403
}
43914404
else
43924405
{
4393-
static const reg::Ex nonBrief(R"( *[\\@]ifile *\"[^\"]*\" *[\\@]ilinebr *[\\@]iline *(\d+) *[\\@]ilinebr( *\n*))");
43944406
std::string str = yyextra->current->brief.str();
43954407
reg::Match match;
4396-
if (reg::match(str,match,nonBrief)) // match found
4408+
if (reg::match(str,match,nonBrief_re)) // match found
43974409
{
43984410
size_t cnt = 0;
43994411
for (size_t i = 0; i < match[2].str().size(); i++)
44004412
{
4401-
if (match[2].str()[i] == '\n') cnt++;
4413+
if (match[2].str()[i] == '\n') cnt++;
44024414
}
44034415
if (cnt)
44044416
{
@@ -4508,10 +4520,9 @@ static void addIlineBreak(yyscan_t yyscanner,int lineNr)
45084520
static void endBrief(yyscan_t yyscanner)
45094521
{
45104522
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
4511-
static const reg::Ex nonBrief(R"( *[\\@]ifile *\"[^\"]*\" *[\\@]ilinebr *[\\@]iline *(\d+) *[\\@]ilinebr( *\n*))");
4512-
std::string str = yyextra->current->brief.str();
4523+
std::string_view str = yyextra->current->brief.view();
45134524
reg::Match match;
4514-
if (!yyextra->current->brief.stripWhiteSpace().isEmpty() && !reg::match(str,match,nonBrief))
4525+
if (!stripWhiteSpace(str).empty() && !reg::match(str,match,nonBrief_re))
45154526
{ // only go to the detailed description if we have
45164527
// found some brief description and not just whitespace
45174528
yyextra->briefEndsAtDot=FALSE;

src/fortranscanner.l

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ struct fortranscannerYY_state
212212
int fixedCommentAfter = 72;
213213
//! counter for the number of main programs in this file
214214
int mainPrograms = 0;
215+
int curIndent = 0;
215216
};
216217

217218
//-----------------------------------------------------------------------------
@@ -1393,7 +1394,7 @@ private {
13931394
{
13941395
yyextra->current = yyextra->last_entry;
13951396
}
1396-
handleCommentBlock(yyscanner,yyextra->docBlock,TRUE);
1397+
handleCommentBlock(yyscanner,stripIndentation(yyextra->docBlock),TRUE);
13971398
// switch back
13981399
yyextra->current = std::move(tmp_entry);
13991400
}
@@ -1409,6 +1410,9 @@ private {
14091410
yyextra->docBlock.clear();
14101411
}
14111412

1413+
<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains,FEnum>^{BS} {
1414+
yyextra->curIndent = computeIndent(yytext);
1415+
}
14121416
<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains,FEnum>"!>" {
14131417
yy_push_state(YY_START,yyscanner);
14141418
yyextra->current->docLine = yyextra->lineNr;
@@ -1522,9 +1526,11 @@ private {
15221526
yyextra->blockLineNr=yyextra->lineNr;
15231527
BEGIN(DocCopyBlock);
15241528
}
1525-
<DocBlock>"\\ilinebr "{B}*"!" {
1529+
<DocBlock>"\\ilinebr "{BS} {
15261530
QCString indent;
1527-
indent.fill(' ',yyleng-9);
1531+
auto extraSpaces = std::max(0,yyleng-9-yyextra->curIndent-1);
1532+
indent.fill(' ',extraSpaces);
1533+
//printf("extraSpaces=%d\n",extraSpaces);
15281534
yyextra->docBlock += "\\ilinebr ";
15291535
yyextra->docBlock += indent;
15301536
}
@@ -1540,7 +1546,7 @@ private {
15401546
//cout <<"3=========> comment block : "<< yyextra->docBlock << endl;
15411547
yyextra->colNr -= 1;
15421548
unput(*yytext);
1543-
handleCommentBlock(yyscanner,yyextra->docBlock,TRUE);
1549+
handleCommentBlock(yyscanner,stripIndentation(yyextra->docBlock),TRUE);
15441550
pop_state(yyscanner);
15451551
}
15461552
<DocBlock>. { // command block

src/pyscanner.l

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ ID [a-z_A-Z%]+{IDSYM}*
421421
BEGIN(TripleComment);
422422
}
423423
424-
{STARTDOCSYMS}/[^#] { // start of a special comment
424+
{B}{STARTDOCSYMS}/[^#] { // start of a special comment
425425
yyextra->curIndent=computeIndent(yytext);
426426
yyextra->packageCommentAllowed = FALSE;
427427
initSpecialBlock(yyscanner);
@@ -1441,7 +1441,7 @@ ID [a-z_A-Z%]+{IDSYM}*
14411441
{
14421442
if (!actualDoc.isEmpty())
14431443
{
1444-
stripIndentation(actualDoc,yyextra->commentIndent);
1444+
stripIndentationVerbatim(actualDoc,yyextra->commentIndent);
14451445
actualDoc.prepend("@iverbatim\n");
14461446
actualDoc.append("@endiverbatim ");
14471447
}
@@ -1456,7 +1456,7 @@ ID [a-z_A-Z%]+{IDSYM}*
14561456
{
14571457
if (!actualDoc.isEmpty())
14581458
{
1459-
stripIndentation(actualDoc,yyextra->commentIndent);
1459+
stripIndentationVerbatim(actualDoc,yyextra->commentIndent);
14601460
actualDoc.prepend("@iverbatim\n");
14611461
actualDoc.append("@endiverbatim ");
14621462
}
@@ -1577,9 +1577,11 @@ ID [a-z_A-Z%]+{IDSYM}*
15771577
({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
15781578
yyextra->docBlock+=yytext;
15791579
}
1580-
"\\ilinebr "{B}*"#" {
1580+
"\\ilinebr "{B}* {
15811581
QCString indent;
1582-
indent.fill(' ',yyleng-9);
1582+
auto extraSpaces = std::max(0,yyleng-9-yyextra->curIndent-1);
1583+
indent.fill(' ',extraSpaces);
1584+
//printf("extraSpaces=%d\n",extraSpaces);
15831585
yyextra->docBlock += "\\ilinebr ";
15841586
yyextra->docBlock += indent;
15851587
}

src/scanner.l

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7003,7 +7003,6 @@ NONLopt [^\n]*
70037003
yyextra->fileName = yyextra->fileName.stripWhiteSpace();
70047004
yyextra->docBlock << yytext;
70057005
}
7006-
<DocBlock>{CMD}"iline"{LINENR}/[\n\.] |
70077006
<DocBlock>{CMD}"iline"{LINENR}{B} {
70087007
bool ok = false;
70097008
int nr = QCString(&yytext[6]).toInt(&ok);

src/util.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6257,18 +6257,33 @@ QCString stripIndentation(const QCString &s)
62576257
indent++;
62586258
}
62596259
}
6260+
else if (c=='\\' && qstrncmp(p,"ilinebr ",8)==0)
6261+
// we also need to remove the indentation after a \ilinebr command at the end of a line
6262+
{
6263+
result << "\\ilinebr ";
6264+
p+=8;
6265+
int skipAmount=0;
6266+
for (int j=0;j<minIndent;j++) if (*(p+j)==' ') skipAmount++; // test to see if we have the indent
6267+
if (skipAmount==minIndent)
6268+
{
6269+
p+=skipAmount; // remove the indent
6270+
}
6271+
}
62606272
else // copy anything until the end of the line
62616273
{
62626274
result << c;
62636275
}
62646276
}
62656277

6278+
//printf("stripIndentation: result=\n%s\n------\n",qPrint(result.str()));
6279+
62666280
return result.str();
62676281
}
62686282

62696283
// strip up to \a indentationLevel spaces from each line in \a doc (excluding the first line)
6270-
void stripIndentation(QCString &doc,const int indentationLevel)
6284+
void stripIndentationVerbatim(QCString &doc,const int indentationLevel)
62716285
{
6286+
//printf("stripIndentationVerbatim(level=%d):\n%s\n------\n",indentationLevel,qPrint(doc));
62726287
if (indentationLevel <= 0 || doc.isEmpty()) return; // nothing to strip
62736288

62746289
// by stripping content the string will only become shorter so we write the results
@@ -6313,6 +6328,7 @@ void stripIndentation(QCString &doc,const int indentationLevel)
63136328
}
63146329
}
63156330
doc.resize(static_cast<uint32_t>(dst-doc.data()));
6331+
//printf("stripIndentationVerbatim: result=\n%s\n------\n",qPrint(doc));
63166332
}
63176333

63186334
bool fileVisibleInIndex(const FileDef *fd,bool &genSourceFile)

src/util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ QCString processMarkup(const QCString &s);
427427
bool protectionLevelVisible(Protection prot);
428428

429429
QCString stripIndentation(const QCString &s);
430-
void stripIndentation(QCString &doc,const int indentationLevel);
430+
void stripIndentationVerbatim(QCString &doc,const int indentationLevel);
431431

432432
QCString getDotImageExtension();
433433

0 commit comments

Comments
 (0)