summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri van Heesch <doxygen@gmail.com>2020-07-28 07:27:45 (GMT)
committerDimitri van Heesch <doxygen@gmail.com>2020-07-28 07:27:45 (GMT)
commit10c1495dc8984ec3b800c290f1c7448e75478da1 (patch)
treeba60fe80191f74382efee14653f82ccb283c3ab8
parent6491b1b25148a87f46422889cf2db1387faa71c8 (diff)
downloadDoxygen-10c1495dc8984ec3b800c290f1c7448e75478da1.zip
Doxygen-10c1495dc8984ec3b800c290f1c7448e75478da1.tar.gz
Doxygen-10c1495dc8984ec3b800c290f1c7448e75478da1.tar.bz2
Better handling of \\ilinebr
- Routines to strip leading and trailing whitespace now also take \\ilinebr into account - Added a number of cases in doctokenizer.l where \\ilinebr wasn't handled yet.
-rw-r--r--src/commentscan.l18
-rw-r--r--src/doctokenizer.l30
-rw-r--r--src/util.cpp15
3 files changed, 52 insertions, 11 deletions
diff --git a/src/commentscan.l b/src/commentscan.l
index 4de7562..3d0ca69 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -2972,7 +2972,23 @@ static void stripTrailingWhiteSpace(QCString &s)
uint len = s.length();
int i = (int)len-1;
char c;
- while (i>=0 && ((c = s.at(i))==' ' || c=='\t' || c=='\r')) i--;
+ while (i>=0)
+ {
+ c = s.at(i);
+ if (c==' ' || c=='\t' || c=='\r') // normal whitespace
+ {
+ i--;
+ }
+ else if (c=='r' && i>=7 && qstrncmp("\\ilinebr",s.data()+i-7,8)==0) // special line break marker
+ {
+ i-=8;
+ }
+ else // non-whitespace
+ {
+ break;
+ }
+ }
+ //printf("stripTrailingWhitespace(%s) i=%d len=%d\n",s.data(),i,len);
if (i!=(int)len-1)
{
s.resize(i+2); // string up to and including char at pos i and \0 terminator
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
index 6ea39d9..51d234b 100644
--- a/src/doctokenizer.l
+++ b/src/doctokenizer.l
@@ -954,6 +954,9 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
unput(*yytext);
return 0;
}
+<St_Title>"\\ilinebr" {
+ return 0;
+ }
<St_TitleN>"&"{ID}";" { /* symbol */
g_token->name = yytext;
return TK_SYMBOL;
@@ -990,6 +993,9 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
unput(*yytext);
return 0;
}
+<St_TitleN>"\\ilinebr" {
+ return 0;
+ }
<St_TitleQ>"&"{ID}";" { /* symbol */
g_token->name = yytext;
return TK_SYMBOL;
@@ -1017,6 +1023,9 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
unput(*yytext);
return 0;
}
+<St_TitleQ>"\\ilinebr" {
+ return 0;
+ }
<St_TitleA>{BLANK}*{ID}{BLANK}*"="{BLANK}* { // title attribute
g_token->name = yytext;
g_token->name = g_token->name.left(g_token->name.find('=')).stripWhiteSpace();
@@ -1035,6 +1044,9 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
unput(*yytext);
return 0;
}
+<St_TitleV,St_TitleA>"\\ilinebr" {
+ return 0;
+ }
<St_Anchor>{LABELID}{WS}? { // anchor
g_token->name = QCString(yytext).stripWhiteSpace();
@@ -1064,6 +1076,9 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
unput(*yytext);
return 0;
}
+<St_Cite>"\\ilinebr" {
+ return 0;
+ }
<St_Cite>. { // any other character
unput(*yytext);
return 0;
@@ -1091,6 +1106,9 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
unput(*yytext);
return 0;
}
+<St_Ref>"\\ilinebr" {
+ return 0;
+ }
<St_Ref>. { // any other character
unput(*yytext);
return 0;
@@ -1150,7 +1168,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
g_token->chars=yytext;
return TK_WHITESPACE;
}
-<St_Ref2>"\""|\n { /* " or \n => end of title */
+<St_Ref2>"\""|\n|"\\ilinebr" { /* " or \n => end of title */
return 0;
}
<St_XRefItem>{LABELID} {
@@ -1246,7 +1264,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
/* State for skipping title (all chars until the end of the line) */
<St_SkipTitle>.
-<St_SkipTitle>\n { return 0; }
+<St_SkipTitle>(\n|"\\ilinebr") { return 0; }
/* State for the pass used to find the anchors and sections */
@@ -1352,9 +1370,9 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
}
<St_SecSkip>[^a-z_A-Z0-9\-\\\@]+
<St_SecSkip>.
-<St_SecSkip>\n
+<St_SecSkip>(\n|"\\ilinebr")
<St_Sections>.
-<St_Sections>\n
+<St_Sections>(\n|"\\ilinebr")
<St_SecLabel1>{LABELID} {
g_secLabel = yytext;
processSection();
@@ -1370,6 +1388,10 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
<St_SecTitle>[^\n]*\n {
g_secTitle = yytext;
g_secTitle = g_secTitle.stripWhiteSpace();
+ if (g_secTitle.right(8)=="\\ilinebr")
+ {
+ g_secTitle.left(g_secTitle.length()-8);
+ }
processSection();
BEGIN(St_Sections);
}
diff --git a/src/util.cpp b/src/util.cpp
index 8b3f618..13ae200 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -6612,10 +6612,11 @@ QCString stripLeadingAndTrailingEmptyLines(const QCString &s,int &docLine)
// search for leading empty lines
int i=0,li=-1,l=s.length();
char c;
- while ((c=*p++))
+ while ((c=*p))
{
- if (c==' ' || c=='\t' || c=='\r') i++;
- else if (c=='\n') i++,li=i,docLine++;
+ if (c==' ' || c=='\t' || c=='\r') i++,p++;
+ else if (c=='\\' && qstrncmp(p,"\\ilinebr",8)==0) i+=8,li=i,docLine++,p+=8;
+ else if (c=='\n') i++,li=i,docLine++,p++;
else break;
}
@@ -6624,9 +6625,10 @@ QCString stripLeadingAndTrailingEmptyLines(const QCString &s,int &docLine)
p=s.data()+b;
while (b>=0)
{
- c=*p; p--;
- if (c==' ' || c=='\t' || c=='\r') b--;
- else if (c=='\n') bi=b,b--;
+ c=*p;
+ if (c==' ' || c=='\t' || c=='\r') b--,p--;
+ else if (c=='r' && b>=7 && qstrncmp(p-7,"\\ilinebr",8)==0) bi=b-7,b-=8,p-=8;
+ else if (c=='\n') bi=b,b--,p--;
else break;
}
@@ -6637,6 +6639,7 @@ QCString stripLeadingAndTrailingEmptyLines(const QCString &s,int &docLine)
if (bi==-1) bi=l;
if (li==-1) li=0;
if (bi<=li) return 0; // only empty lines
+ //printf("docLine='%s' len=%d li=%d bi=%d\n",s.data(),s.length(),li,bi);
return s.mid(li,bi-li);
}