summaryrefslogtreecommitdiffstats
path: root/src/markdown.cpp
diff options
context:
space:
mode:
authorDimitri van Heesch <doxygen@gmail.com>2021-04-29 17:26:11 (GMT)
committerGitHub <noreply@github.com>2021-04-29 17:26:11 (GMT)
commitb8a3ff6c33264c43cdf30c04baa9793e7e8d51a2 (patch)
tree9d60ced4b8fceb00c068b56d699c1ba57540d415 /src/markdown.cpp
parent4dba9fbdda10889d2285b85b7e9ff6282b34fccf (diff)
parentc6d77227efaf332a5d24bc12d32f4b1fec6b13b9 (diff)
downloadDoxygen-b8a3ff6c33264c43cdf30c04baa9793e7e8d51a2.zip
Doxygen-b8a3ff6c33264c43cdf30c04baa9793e7e8d51a2.tar.gz
Doxygen-b8a3ff6c33264c43cdf30c04baa9793e7e8d51a2.tar.bz2
Merge branch 'master' into feature/bug_305773
Diffstat (limited to 'src/markdown.cpp')
-rw-r--r--src/markdown.cpp218
1 files changed, 118 insertions, 100 deletions
diff --git a/src/markdown.cpp b/src/markdown.cpp
index 2bc8206..4627e73 100644
--- a/src/markdown.cpp
+++ b/src/markdown.cpp
@@ -32,12 +32,10 @@
*/
#include <stdio.h>
-#include <qglobal.h>
-#include <qregexp.h>
-#include <qfileinfo.h>
#include <unordered_map>
#include <functional>
+#include <atomic>
#include "markdown.h"
#include "growbuf.h"
@@ -51,6 +49,9 @@
#include "section.h"
#include "message.h"
#include "portable.h"
+#include "regex.h"
+#include "fileinfo.h"
+#include "utf8.h"
#if !defined(NDEBUG)
#define ENABLE_TRACING
@@ -68,22 +69,22 @@
class Trace
{
public:
- Trace(const char *func) : m_func(func)
+ Trace(const QCString &func) : m_func(func)
{
if (Debug::isFlagSet(Debug::Markdown))
{
- fprintf(IOSTREAM,"> %s\n",func);
+ fprintf(IOSTREAM,"> %s\n",qPrint(func));
s_indent++;
}
}
- Trace(const char *func,const char *data) : m_func(func)
+ Trace(const QCString &func,const QCString &data) : m_func(func)
{
if (Debug::isFlagSet(Debug::Markdown))
{
indent();
char data_s[DATA_BUFSIZE*2+1] = ""; // worst case each input char outputs 2 chars + 0 terminator.
int j=0;
- if (data)
+ if (!data.isEmpty())
{
for (int i=0;i<DATA_BUFSIZE;i++)
{
@@ -97,7 +98,7 @@ class Trace
}
}
data_s[j++]=0;
- fprintf(IOSTREAM,"> %s data=[%s…]\n",func,data_s);
+ fprintf(IOSTREAM,"> %s data=[%s…]\n",qPrint(func),data_s);
s_indent++;
}
}
@@ -107,7 +108,7 @@ class Trace
{
s_indent--;
indent();
- fprintf(IOSTREAM,"< %s\n",m_func);
+ fprintf(IOSTREAM,"< %s\n",qPrint(m_func));
}
}
void trace(const char *fmt,...)
@@ -115,7 +116,7 @@ class Trace
if (Debug::isFlagSet(Debug::Markdown))
{
indent();
- fprintf(IOSTREAM,": %s: ",m_func);
+ fprintf(IOSTREAM,": %s: ",qPrint(m_func));
va_list args;
va_start(args,fmt);
vfprintf(IOSTREAM, fmt, args);
@@ -124,7 +125,7 @@ class Trace
}
private:
void indent() { for (int i=0;i<s_indent;i++) fputs(" ",IOSTREAM); }
- const char *m_func;
+ QCString m_func;
static int s_indent;
};
@@ -172,7 +173,7 @@ struct TableCell
bool colSpan;
};
-Markdown::Markdown(const char *fileName,int lineNr,int indentLevel)
+Markdown::Markdown(const QCString &fileName,int lineNr,int indentLevel)
: m_fileName(fileName), m_lineNr(lineNr), m_indentLevel(indentLevel)
{
using namespace std::placeholders;
@@ -213,14 +214,34 @@ inline int isNewline(const char *data)
return 0;
}
+// escape double quotes in string
+static QCString escapeDoubleQuotes(const QCString &s)
+{
+ TRACE(s);
+ if (s.isEmpty()) return s;
+ GrowBuf growBuf;
+ const char *p=s.data();
+ char c,pc='\0';
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '"': if (pc!='\\') { growBuf.addChar('\\'); } growBuf.addChar(c); break;
+ default: growBuf.addChar(c); break;
+ }
+ pc=c;
+ }
+ growBuf.addChar(0);
+ return growBuf.get();
+}
// escape characters that have a special meaning later on.
static QCString escapeSpecialChars(const QCString &s)
{
- TRACE(s.data());
- if (s.isEmpty()) return "";
+ TRACE(s);
+ if (s.isEmpty()) return s;
bool insideQuote=FALSE;
GrowBuf growBuf;
- const char *p=s;
+ const char *p=s.data();
char c,pc='\0';
while ((c=*p++))
{
@@ -242,11 +263,9 @@ static QCString escapeSpecialChars(const QCString &s)
static void convertStringFragment(QCString &result,const char *data,int size)
{
- TRACE(result.data());
+ TRACE(result);
if (size<0) size=0;
- result.resize(size+1);
- memcpy(result.rawData(),data,size);
- result.at(size)='\0';
+ result = QCString(data,(uint)size);
}
/** helper function to convert presence of left and/or right alignment markers
@@ -414,7 +433,7 @@ int Markdown::findEmphasisChar(const char *data, int size, char c, int c_size)
if ((data[i]=='\\' || data[i]=='@') && // command
data[i-1]!='\\' && data[i-1]!='@') // not escaped
{
- if (qstrncmp(&data[i+1],endBlockName,l)==0)
+ if (qstrncmp(&data[i+1],endBlockName.data(),l)==0)
{
break;
}
@@ -676,13 +695,13 @@ int Markdown::processHtmlTagWrite(const char *data,int offset,int size,bool doWr
{
if (data[i]=='/' && i<size-1 && data[i+1]=='>') // <bla/>
{
- //printf("Found htmlTag={%s}\n",QCString(data).left(i+2).data());
+ //printf("Found htmlTag={%s}\n",qPrint(QCString(data).left(i+2)));
if (doWrite) m_out.addStr(data,i+2);
return i+2;
}
else if (data[i]=='>') // <bla>
{
- //printf("Found htmlTag={%s}\n",QCString(data).left(i+1).data());
+ //printf("Found htmlTag={%s}\n",qPrint(QCString(data).left(i+1)));
if (doWrite) m_out.addStr(data,i+1);
return i+1;
}
@@ -702,7 +721,7 @@ int Markdown::processHtmlTagWrite(const char *data,int offset,int size,bool doWr
}
else if (!insideAttr && data[i]=='>') // found end of tag
{
- //printf("Found htmlTag={%s}\n",QCString(data).left(i+1).data());
+ //printf("Found htmlTag={%s}\n",qPrint(QCString(data).left(i+1)));
if (doWrite) m_out.addStr(data,i+1);
return i+1;
}
@@ -775,13 +794,13 @@ void Markdown::writeMarkdownImage(const char *fmt, bool explicitTitle,
if (!explicitTitle && !content.isEmpty())
{
m_out.addStr(" \"");
- m_out.addStr(content);
+ m_out.addStr(escapeDoubleQuotes(content));
m_out.addStr("\"");
}
else if ((content.isEmpty() || explicitTitle) && !title.isEmpty())
{
m_out.addStr(" \"");
- m_out.addStr(title);
+ m_out.addStr(escapeDoubleQuotes(title));
m_out.addStr("\"");
}
else
@@ -841,7 +860,7 @@ int Markdown::processLink(const char *data,int,int size)
if (i>=size) return 0; // premature end of comment -> no link
contentEnd=i;
convertStringFragment(content,data+contentStart,contentEnd-contentStart);
- //printf("processLink: content={%s}\n",content.data());
+ //printf("processLink: content={%s}\n",qPrint(content));
if (!isImageLink && content.isEmpty()) return 0; // no link text
i++; // skip over ]
@@ -890,7 +909,7 @@ int Markdown::processLink(const char *data,int,int size)
if (i>=size || data[i]=='\n') return 0;
convertStringFragment(link,data+linkStart,i-linkStart);
link = link.stripWhiteSpace();
- //printf("processLink: link={%s}\n",link.data());
+ //printf("processLink: link={%s}\n",qPrint(link));
if (link.isEmpty()) return 0;
if (link.at(link.length()-1)=='>') link=link.left(link.length()-1);
@@ -920,7 +939,7 @@ int Markdown::processLink(const char *data,int,int size)
if (data[titleEnd]==c) // found it
{
convertStringFragment(title,data+titleStart,titleEnd-titleStart);
- //printf("processLink: title={%s}\n",title.data());
+ //printf("processLink: title={%s}\n",qPrint(title));
}
else
{
@@ -947,7 +966,7 @@ int Markdown::processLink(const char *data,int,int size)
if (i>=size) return 0;
// extract link
convertStringFragment(link,data+linkStart,i-linkStart);
- //printf("processLink: link={%s}\n",link.data());
+ //printf("processLink: link={%s}\n",qPrint(link));
link = link.stripWhiteSpace();
if (link.isEmpty()) // shortcut link
{
@@ -960,11 +979,11 @@ int Markdown::processLink(const char *data,int,int size)
{
link = lr_it->second.link;
title = lr_it->second.title;
- //printf("processLink: ref: link={%s} title={%s}\n",link.data(),title.data());
+ //printf("processLink: ref: link={%s} title={%s}\n",qPrint(link),qPrint(title));
}
else // reference not found!
{
- //printf("processLink: ref {%s} do not exist\n",link.lower().data());
+ //printf("processLink: ref {%s} do not exist\n",link.qPrint(lower()));
return 0;
}
i++;
@@ -973,7 +992,7 @@ int Markdown::processLink(const char *data,int,int size)
{
QCString content_lower = content.lower();
auto lr_it = m_linkRefs.find(content_lower.str());
- //printf("processLink: minimal link {%s} lr=%p",content.data(),lr);
+ //printf("processLink: minimal link {%s} lr=%p",qPrint(content),lr);
if (lr_it!=m_linkRefs.end()) // found it
{
link = lr_it->second.link;
@@ -1049,16 +1068,16 @@ int Markdown::processLink(const char *data,int,int size)
m_out.addStr("@ref ");
if (!(Portable::isAbsolutePath(link) || isURL(link)))
{
- QFileInfo forg(link);
+ FileInfo forg(link.str());
if (forg.exists() && forg.isReadable())
{
- link = forg.absFilePath().data();
+ link = forg.absFilePath();
}
else if (!(forg.exists() && forg.isReadable()))
{
- QFileInfo fi(m_fileName);
- QCString mdFile = m_fileName.left(m_fileName.length()-fi.fileName().length()) + link;
- QFileInfo fmd(mdFile);
+ FileInfo fi(m_fileName.str());
+ QCString mdFile = m_fileName.left(m_fileName.length()-(uint)fi.fileName().length()) + link;
+ FileInfo fmd(mdFile.str());
if (fmd.exists() && fmd.isReadable())
{
link = fmd.absFilePath().data();
@@ -1092,12 +1111,12 @@ int Markdown::processLink(const char *data,int,int size)
}
m_out.addStr(">");
content = content.simplifyWhiteSpace();
- processInline(content,content.length());
+ processInline(content.data(),content.length());
m_out.addStr("</a>");
}
else // avoid link to e.g. F[x](y)
{
- //printf("no link for '%s'\n",link.data());
+ //printf("no link for '%s'\n",qPrint(link));
return 0;
}
}
@@ -1165,7 +1184,7 @@ int Markdown::processCodeSpan(const char *data, int /*offset*/, int size)
f_end--;
}
- //printf("found code span '%s'\n",QCString(data+f_begin).left(f_end-f_begin).data());
+ //printf("found code span '%s'\n",qPrint(QCString(data+f_begin).left(f_end-f_begin)));
/* real code span */
if (f_begin < f_end)
@@ -1207,7 +1226,7 @@ int Markdown::processSpecialCommand(const char *data, int offset, int size)
if ((data[i]=='\\' || data[i]=='@') && // command
data[i-1]!='\\' && data[i-1]!='@') // not escaped
{
- if (qstrncmp(&data[i+1],endBlockName,l)==0)
+ if (qstrncmp(&data[i+1],endBlockName.data(),l)==0)
{
//printf("found end at %d\n",i);
addStrEscapeUtf8Nbsp(data,i+1+l);
@@ -1344,7 +1363,7 @@ static int isLinkRef(const char *data,int size,
if (i>=size || data[i]!=']') return 0;
convertStringFragment(refid,data+refIdStart,i-refIdStart);
if (refid.isEmpty()) return 0;
- //printf(" isLinkRef: found refid='%s'\n",refid.data());
+ //printf(" isLinkRef: found refid='%s'\n",qPrint(refid));
i++;
if (i>=size || data[i]!=':') return 0;
i++;
@@ -1365,7 +1384,7 @@ static int isLinkRef(const char *data,int size,
if (i<size && data[i]=='>') i++;
if (linkStart==linkEnd) return 0; // empty link
convertStringFragment(link,data+linkStart,linkEnd-linkStart);
- //printf(" isLinkRef: found link='%s'\n",link.data());
+ //printf(" isLinkRef: found link='%s'\n",qPrint(link));
if (link=="@ref" || link=="\\ref")
{
int argStart=i;
@@ -1410,7 +1429,7 @@ static int isLinkRef(const char *data,int size,
{
convertStringFragment(title,data+titleStart,end-titleStart);
}
- //printf(" title found: '%s'\n",title.data());
+ //printf(" title found: '%s'\n",qPrint(title));
}
while (i<size && data[i]==' ') i++;
//printf("end of isLinkRef: i=%d size=%d data[i]='%c' eol=%d\n",
@@ -1450,16 +1469,16 @@ static int isHRuler(const char *data,int size)
static QCString extractTitleId(QCString &title, int level)
{
- TRACE(title.data());
- //static QRegExp r1("^[a-z_A-Z][a-z_A-Z0-9\\-]*:");
- static QRegExp r2("\\{#[a-z_A-Z][a-z_A-Z0-9\\-]*\\}");
- int l=0;
- int i = r2.match(title,0,&l);
- if (i!=-1 && title.mid(i+l).stripWhiteSpace().isEmpty()) // found {#id} style id
- {
- QCString id = title.mid(i+2,l-3);
- title = title.left(i);
- //printf("found id='%s' title='%s'\n",id.data(),title.data());
+ TRACE(title);
+ // match e.g. '{#id-b11} ' and capture 'id-b11'
+ static const reg::Ex r2(R"({#(\a[\w-]*)}\s*$)");
+ reg::Match match;
+ std::string ti = title.str();
+ if (reg::search(ti,match,r2))
+ {
+ std::string id = match[1].str();
+ title = title.left((int)match.position());
+ //printf("found match id='%s' title=%s\n",id.c_str(),qPrint(title));
return id;
}
if ((level > 0) && (level <= Config_getInt(TOC_INCLUDE_HEADINGS)))
@@ -1467,10 +1486,10 @@ static QCString extractTitleId(QCString &title, int level)
static AtomicInt autoId { 0 };
QCString id;
id.sprintf("autotoc_md%d",autoId++);
- //printf("auto-generated id='%s' title='%s'\n",id.data(),title.data());
+ //printf("auto-generated id='%s' title='%s'\n",qPrint(id),qPrint(title));
return id;
}
- //printf("no id found in title '%s'\n",title.data());
+ //printf("no id found in title '%s'\n",qPrint(title));
return "";
}
@@ -1620,7 +1639,7 @@ static int computeIndentExcludingListMarkers(const char *data,int size)
}
indent++,i++;
}
- //printf("{%s}->%d\n",QCString(data).left(size).data(),indent);
+ //printf("{%s}->%d\n",QCString(data).qPrint(left(size)),indent);
return indent;
}
@@ -1710,8 +1729,8 @@ static bool isCodeBlock(const char *data,int offset,int size,int &indent)
{
//printf(" positions: nl_pos=[%d,%d,%d] line[-2]='%s' line[-1]='%s'\n",
// nl_pos[0],nl_pos[1],nl_pos[2],
- // QCString(data+nl_pos[1]).left(nl_pos[0]-nl_pos[1]-1).data(),
- // QCString(data+nl_pos[2]).left(nl_pos[1]-nl_pos[2]-1).data());
+ // qPrint(QCString(data+nl_pos[1]).left(nl_pos[0]-nl_pos[1]-1)),
+ // qPrint(QCString(data+nl_pos[2]).left(nl_pos[1]-nl_pos[2]-1)));
// check that line -1 is empty
if (!isEmptyLine(data+nl_pos[1],nl_pos[0]-nl_pos[1]-1))
@@ -2156,7 +2175,7 @@ int Markdown::writeCodeBlock(const char *data,int size,int refIndent)
{
TRACE(data);
int i=0,end;
- //printf("writeCodeBlock: data={%s}\n",QCString(data).left(size).data());
+ //printf("writeCodeBlock: data={%s}\n",qPrint(QCString(data).left(size)));
// no need for \ilinebr here as the previous line was empty and was skipped
m_out.addStr("@verbatim\n");
int emptyLines=0;
@@ -2169,7 +2188,7 @@ int Markdown::writeCodeBlock(const char *data,int size,int refIndent)
int indent=0;
while (j<end && data[j]==' ') j++,indent++;
//printf("j=%d end=%d indent=%d refIndent=%d tabSize=%d data={%s}\n",
- // j,end,indent,refIndent,Config_getInt(TAB_SIZE),QCString(data+i).left(end-i-1).data());
+ // j,end,indent,refIndent,Config_getInt(TAB_SIZE),qPrint(QCString(data+i).left(end-i-1)));
if (j==end-1) // empty line
{
emptyLines++;
@@ -2233,10 +2252,10 @@ void Markdown::findEndOfLine(const char *data,int size,
data[end-1]!='\\' && data[end-1]!='@'
)
{
- if (qstrncmp(&data[end+1],endBlockName,l)==0)
+ if (qstrncmp(&data[end+1],endBlockName.data(),l)==0)
{
// found end marker, skip over this block
- //printf("feol.block m_out={%s}\n",QCString(data+i).left(end+l+1-i).data());
+ //printf("feol.block m_out={%s}\n",qPrint(QCString(data+i).left(end+l+1-i)));
end = end + l + 2;
break;
}
@@ -2276,7 +2295,7 @@ void Markdown::findEndOfLine(const char *data,int size,
}
}
if (j>0) end+=j-1;
- //printf("findEndOfLine pi=%d i=%d end=%d {%s}\n",pi,i,end,QCString(data+i).left(end-i).data());
+ //printf("findEndOfLine pi=%d i=%d end=%d {%s}\n",pi,i,end,qPrint(QCString(data+i).left(end-i)));
}
void Markdown::writeFencedCodeBlock(const char *data,const char *lng,
@@ -2296,7 +2315,7 @@ void Markdown::writeFencedCodeBlock(const char *data,const char *lng,
QCString Markdown::processQuotations(const QCString &s,int refIndent)
{
- TRACE(s.data());
+ TRACE(s);
m_out.clear();
const char *data = s.data();
int size = s.length();
@@ -2312,7 +2331,7 @@ QCString Markdown::processQuotations(const QCString &s,int refIndent)
{
if (isFencedCodeBlock(data+pi,size-pi,refIndent,lang,blockStart,blockEnd,blockOffset))
{
- writeFencedCodeBlock(data+pi,lang,blockStart,blockEnd);
+ writeFencedCodeBlock(data+pi,lang.data(),blockStart,blockEnd);
i=pi+blockOffset;
pi=-1;
end=i+1;
@@ -2348,14 +2367,14 @@ QCString Markdown::processQuotations(const QCString &s,int refIndent)
m_out.addChar(0);
//printf("Process quotations\n---- input ----\n%s\n---- output ----\n%s\n------------\n",
- // s.data(),m_out.get());
+ // qPrint(s),m_out.get());
return m_out.get();
}
QCString Markdown::processBlocks(const QCString &s,int indent)
{
- TRACE(s.data());
+ TRACE(s);
m_out.clear();
const char *data = s.data();
int size = s.length();
@@ -2420,7 +2439,7 @@ QCString Markdown::processBlocks(const QCString &s,int indent)
if ((data[i]=='\\' || data[i]=='@') && // command
data[i-1]!='\\' && data[i-1]!='@') // not escaped
{
- if (qstrncmp(&data[i+1],endBlockName,l)==0)
+ if (qstrncmp(&data[i+1],endBlockName.data(),l)==0)
{
m_out.addChar(data[i]);
m_out.addStr(endBlockName);
@@ -2440,7 +2459,7 @@ QCString Markdown::processBlocks(const QCString &s,int indent)
QCString header;
convertStringFragment(header,data+pi,i-pi-1);
id = extractTitleId(header, level);
- //printf("header='%s' is='%s'\n",header.data(),id.data());
+ //printf("header='%s' is='%s'\n",qPrint(header),qPrint(id));
if (!header.isEmpty())
{
if (!id.isEmpty())
@@ -2470,7 +2489,7 @@ QCString Markdown::processBlocks(const QCString &s,int indent)
else if ((ref=isLinkRef(data+pi,size-pi,id,link,title)))
{
//printf("found link ref: id='%s' link='%s' title='%s'\n",
- // id.data(),link.data(),title.data());
+ // qPrint(id),qPrint(link),qPrint(title));
m_linkRefs.insert({id.lower().str(),LinkRef(link,title)});
i=ref+pi;
pi=-1;
@@ -2479,8 +2498,8 @@ QCString Markdown::processBlocks(const QCString &s,int indent)
else if (isFencedCodeBlock(data+pi,size-pi,indent,lang,blockStart,blockEnd,blockOffset))
{
//printf("Found FencedCodeBlock lang='%s' start=%d end=%d code={%s}\n",
- // lang.data(),blockStart,blockEnd,QCString(data+pi+blockStart).left(blockEnd-blockStart).data());
- writeFencedCodeBlock(data+pi,lang,blockStart,blockEnd);
+ // qPrint(lang),blockStart,blockEnd,QCString(data+pi+blockStart).left(blockEnd-blockStart).data());
+ writeFencedCodeBlock(data+pi,lang.data(),blockStart,blockEnd);
i=pi+blockOffset;
pi=-1;
end=i+1;
@@ -2515,7 +2534,7 @@ QCString Markdown::processBlocks(const QCString &s,int indent)
if (isLinkRef(data+pi,size-pi,id,link,title))
{
//printf("found link ref: id='%s' link='%s' title='%s'\n",
- // id.data(),link.data(),title.data());
+ // qPrint(id),qPrint(link),qPrint(title));
m_linkRefs.insert({id.lower().str(),LinkRef(link,title)});
}
else
@@ -2531,7 +2550,7 @@ QCString Markdown::processBlocks(const QCString &s,int indent)
/** returns TRUE if input string docs starts with \@page or \@mainpage command */
static bool isExplicitPage(const QCString &docs)
{
- TRACE(docs.data());
+ TRACE(docs);
int i=0;
const char *data = docs.data();
if (data)
@@ -2554,7 +2573,7 @@ static bool isExplicitPage(const QCString &docs)
QCString Markdown::extractPageTitle(QCString &docs,QCString &id, int &prepend)
{
- TRACE(docs.data());
+ TRACE(docs);
// first first non-empty line
prepend = 0;
QCString title;
@@ -2597,13 +2616,13 @@ QCString Markdown::extractPageTitle(QCString &docs,QCString &id, int &prepend)
docs=docs_org;
id = extractTitleId(title, 0);
}
- //printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",title.data(),docs.data(),id.data());
+ //printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",qPrint(title),qPrint(docs),qPrint(id));
return title;
}
QCString Markdown::detab(const QCString &s,int &refIndent)
{
- TRACE(s.data());
+ TRACE(s);
int tabSize = Config_getInt(TAB_SIZE);
int size = s.length();
m_out.clear();
@@ -2638,23 +2657,21 @@ QCString Markdown::detab(const QCString &s,int &refIndent)
if (c<0 && i<size) // multibyte sequence
{
// special handling of the UTF-8 nbsp character 0xC2 0xA0
- if ((uchar)c == 0xC2 && (uchar)(data[i]) == 0xA0)
+ int nb = isUTF8NonBreakableSpace(data);
+ if (nb>0)
{
m_out.addStr(g_doxy_nsbp);
- i++;
+ i+=nb-1;
}
else
{
- m_out.addChar(c);
- m_out.addChar(data[i++]); // >= 2 bytes
- if (((uchar)c&0xE0)==0xE0 && i<size)
+ int bytes = getUTF8CharNumBytes(c);
+ for (int j=0;j<bytes-1 && c;j++)
{
- m_out.addChar(data[i++]); // 3 bytes
- }
- if (((uchar)c&0xF0)==0xF0 && i<size)
- {
- m_out.addChar(data[i++]); // 4 byres
+ m_out.addChar(c);
+ c = data[i++];
}
+ m_out.addChar(c);
}
}
else
@@ -2682,19 +2699,19 @@ QCString Markdown::process(const QCString &input, int &startNewlines)
QCString s = input;
if (s.at(s.length()-1)!='\n') s += "\n"; // see PR #6766
s = detab(s,refIndent);
- //printf("======== DeTab =========\n---- output -----\n%s\n---------\n",s.data());
+ //printf("======== DeTab =========\n---- output -----\n%s\n---------\n",qPrint(s));
// then process quotation blocks (as these may contain other blocks)
s = processQuotations(s,refIndent);
- //printf("======== Quotations =========\n---- output -----\n%s\n---------\n",s.data());
+ //printf("======== Quotations =========\n---- output -----\n%s\n---------\n",qPrint(s));
// then process block items (headers, rules, and code blocks, references)
s = processBlocks(s,refIndent);
- //printf("======== Blocks =========\n---- output -----\n%s\n---------\n",s.data());
+ //printf("======== Blocks =========\n---- output -----\n%s\n---------\n",qPrint(s));
// finally process the inline markup (links, emphasis and code spans)
m_out.clear();
- processInline(s,s.length());
+ processInline(s.data(),s.length());
m_out.addChar(0);
Debug::print(Debug::Markdown,0,"======== Markdown =========\n---- input ------- \n%s\n---- output -----\n%s\n=========\n",qPrint(input),qPrint(m_out.get()));
@@ -2710,7 +2727,7 @@ QCString Markdown::process(const QCString &input, int &startNewlines)
if (p>result.data())
{
// strip part of the input
- result = result.mid(p-result.data());
+ result = result.mid(static_cast<int>(p-result.data()));
}
return result;
}
@@ -2719,8 +2736,9 @@ QCString Markdown::process(const QCString &input, int &startNewlines)
QCString markdownFileNameToId(const QCString &fileName)
{
- TRACE(fileName.data());
- QCString baseFn = stripFromPath(QFileInfo(fileName).absFilePath().utf8());
+ TRACE(fileName);
+ std::string absFileName = FileInfo(fileName.str()).absFilePath();
+ QCString baseFn = stripFromPath(absFileName.c_str());
int i = baseFn.findRev('.');
if (i!=-1) baseFn = baseFn.left(i);
QCString baseName = baseFn;
@@ -2750,7 +2768,7 @@ MarkdownOutlineParser::~MarkdownOutlineParser()
{
}
-void MarkdownOutlineParser::parseInput(const char *fileName,
+void MarkdownOutlineParser::parseInput(const QCString &fileName,
const char *fileBuf,
const std::shared_ptr<Entry> &root,
ClangTUParser* /*clangParser*/)
@@ -2768,7 +2786,7 @@ void MarkdownOutlineParser::parseInput(const char *fileName,
if (id.startsWith("autotoc_md")) id = "";
int indentLevel=title.isEmpty() ? 0 : -1;
markdown.setIndentLevel(indentLevel);
- QCString fn = QFileInfo(fileName).fileName().utf8();
+ QCString fn = FileInfo(fileName.str()).fileName();
QCString titleFn = stripExtensionGeneral(fn,getFileNameExtension(fn));
QCString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
bool wasEmpty = id.isEmpty();
@@ -2777,8 +2795,8 @@ void MarkdownOutlineParser::parseInput(const char *fileName,
{
if (!mdfileAsMainPage.isEmpty() &&
(fn==mdfileAsMainPage || // name reference
- QFileInfo(fileName).absFilePath()==
- QFileInfo(mdfileAsMainPage).absFilePath()) // file reference with path
+ FileInfo(fileName.str()).absFilePath()==
+ FileInfo(mdfileAsMainPage.str()).absFilePath()) // file reference with path
)
{
docs.prepend("@anchor " + id + "\\ilinebr ");
@@ -2835,7 +2853,7 @@ void MarkdownOutlineParser::parseInput(const char *fileName,
p->commentScanner.leaveFile(fileName,lineNr);
}
-void MarkdownOutlineParser::parsePrototype(const char *text)
+void MarkdownOutlineParser::parsePrototype(const QCString &text)
{
Doxygen::parserManager->getOutlineParser("*.cpp")->parsePrototype(text);
}