summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/classdef.cpp5
-rw-r--r--src/commentcnv.l36
-rw-r--r--src/commentscan.l2
-rwxr-xr-xsrc/configgen.py67
-rw-r--r--src/context.cpp602
-rw-r--r--src/context.h38
-rw-r--r--src/dirdef.cpp8
-rw-r--r--src/docparser.cpp1
-rw-r--r--src/docparser.h6
-rw-r--r--src/doxygen.cpp49
-rw-r--r--src/htmldocvisitor.cpp7
-rw-r--r--src/htmlgen.cpp109
-rw-r--r--src/htmlgen.h1
-rw-r--r--src/index.cpp42
-rw-r--r--src/lexcode.l24
-rw-r--r--src/lexscanner.l26
-rw-r--r--src/memberdef.cpp15
-rw-r--r--src/memberdef.h2
-rw-r--r--src/pre.l50
-rw-r--r--src/pycode.l2
-rw-r--r--src/pyscanner.l34
-rw-r--r--src/qcstring.h13
-rw-r--r--src/resourcemgr.cpp10
-rw-r--r--src/resourcemgr.h2
-rw-r--r--src/scanner.l39
-rw-r--r--src/searchindex.cpp1
-rwxr-xr-xsrc/template.cpp311
-rw-r--r--src/template.h17
28 files changed, 1171 insertions, 348 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 9f2fe12..7c46c3a 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -2893,7 +2893,7 @@ void ClassDefImpl::writeMemberList(OutputList &ol) const
first = false;
}
ol.writeString(" <tr");
- if ((idx&1)==0) ol.writeString(" class=\"even\"");
+ if ((idx&1)==0) ol.writeString(" class=\"even\""); else ol.writeString(" class=\"odd\"");
idx++;
ol.writeString("><td class=\"entry\">");
if (cd->isObjectiveC())
@@ -2951,7 +2951,7 @@ void ClassDefImpl::writeMemberList(OutputList &ol) const
first = false;
}
ol.writeString(" <tr bgcolor=\"#f0f0f0\"");
- if ((idx&1)==0) ol.writeString(" class=\"even\"");
+ if ((idx&1)==0) ol.writeString(" class=\"even\""); else ol.writeString(" class=\"odd\"");
idx++;
ol.writeString("><td class=\"entry\">");
if (cd->isObjectiveC())
@@ -3406,6 +3406,7 @@ void ClassDefImpl::mergeMembers()
{
// merge the members in the base class of this inheritance branch first
bClass->mergeMembers();
+ if (bClass->getLanguage()==SrcLangExt_Python) continue; // python does not have member overloading, see issue 8480
const MemberNameInfoLinkedMap &srcMnd = bClass->memberNameInfoLinkedMap();
MemberNameInfoLinkedMap &dstMnd = m_impl->allMemberNameInfoLinkedMap;
diff --git a/src/commentcnv.l b/src/commentcnv.l
index d331fa4..aaf1162 100644
--- a/src/commentcnv.l
+++ b/src/commentcnv.l
@@ -134,6 +134,7 @@ MAILADR ("mailto:")?[a-z_A-Z0-9.+-]+"@"[a-z_A-Z0-9-]+("."[a-z_A-Z0-9\-]+)+[a-z
%x SkipChar
%x SComment
%x CComment
+%x CNComment
%x Verbatim
%x VerbatimCode
%x ReadLine
@@ -346,7 +347,10 @@ SLASHopt [/]*
yyextra->nestingCount=1;
clearCommentStack(yyscanner); /* to be on the save side */
copyToOutput(yyscanner,yytext,(int)yyleng);
- BEGIN(CComment);
+ if (yyextra->specialComment)
+ BEGIN(CComment);
+ else
+ BEGIN(CNComment);
yyextra->commentStack.push(yyextra->lineNr);
}
<Scan>"#"("#")? {
@@ -402,8 +406,8 @@ SLASHopt [/]*
yyextra->commentStack.push(yyextra->lineNr);
}
}
-<CComment,ReadLine>{MAILADR} |
-<CComment,ReadLine>"<"{MAILADR}">" { // Mail address, to prevent seeing e.g x@code-factory.org as start of a code block
+<CComment,CNComment,ReadLine>{MAILADR} |
+<CComment,CNComment,ReadLine>"<"{MAILADR}">" { // Mail address, to prevent seeing e.g x@code-factory.org as start of a code block
copyToOutput(yyscanner,yytext,(int)yyleng);
}
<CComment>"{@code"/[ \t\n] {
@@ -618,10 +622,10 @@ SLASHopt [/]*
copyToOutput(yyscanner,yytext,(int)yyleng);
}
-<CComment>[^ `~<\\!@*\n{\"\/]* { /* anything that is not a '*' or command */
+<CComment,CNComment>[^ `~<\\!@*\n{\"\/]* { /* anything that is not a '*' or command */
copyToOutput(yyscanner,yytext,(int)yyleng);
}
-<CComment>"*"+[^*\/\\@\n{\"]* { /* stars without slashes */
+<CComment,CNComment>"*"+[^*\/\\@\n{\"]* { /* stars without slashes */
copyToOutput(yyscanner,yytext,(int)yyleng);
}
<CComment>"\"\"\"" { /* end of Python docstring */
@@ -637,7 +641,7 @@ SLASHopt [/]*
BEGIN(Scan);
}
}
-<CComment>\n { /* new line in comment */
+<CComment,CNComment>\n { /* new line in comment */
copyToOutput(yyscanner,yytext,(int)yyleng);
/* in case of Fortran always end of comment */
if (yyextra->lang==SrcLangExt_Fortran)
@@ -645,7 +649,7 @@ SLASHopt [/]*
BEGIN(Scan);
}
}
-<CComment>"/"+"*" { /* nested C comment */
+<CComment,CNComment>"/"+"*" { /* nested C comment */
if (yyextra->lang==SrcLangExt_Python ||
yyextra->lang==SrcLangExt_Markdown)
{
@@ -655,7 +659,7 @@ SLASHopt [/]*
yyextra->commentStack.push(yyextra->lineNr);
copyToOutput(yyscanner,yytext,(int)yyleng);
}
-<CComment>"*"+"/" { /* end of C comment */
+<CComment,CNComment>"*"+"/" { /* end of C comment */
if (yyextra->lang==SrcLangExt_Python ||
yyextra->lang==SrcLangExt_Markdown)
{
@@ -676,8 +680,8 @@ SLASHopt [/]*
}
}
}
- /* Python an VHDL share CComment, so special attention for ending comments is required */
-<CComment>"\n"/[ \t]*"#" {
+ /* Python an VHDL share CComment,CNComment, so special attention for ending comments is required */
+<CComment,CNComment>"\n"/[ \t]*"#" {
if (yyextra->lang!=SrcLangExt_VHDL)
{
REJECT;
@@ -696,7 +700,7 @@ SLASHopt [/]*
}
}
}
-<CComment>"\n"/[ \t]*"-" {
+<CComment,CNComment>"\n"/[ \t]*"-" {
if (yyextra->lang!=SrcLangExt_Python || yyextra->pythonDocString)
{
REJECT;
@@ -707,7 +711,7 @@ SLASHopt [/]*
BEGIN(Scan);
}
}
-<CComment>"\n"/[ \t]*[^ \t#\-] {
+<CComment,CNComment>"\n"/[ \t]*[^ \t#\-] {
if (yyextra->lang==SrcLangExt_Python)
{
if (yyextra->pythonDocString)
@@ -739,18 +743,18 @@ SLASHopt [/]*
}
}
/* removed for bug 674842 (bug was introduced in rev 768)
-<CComment>"'" {
+<CComment,CNComment>"'" {
yyextra->charContext = YY_START;
copyToOutput(yyscanner,yytext,(int)yyleng);
BEGIN(SkipChar);
}
-<CComment>"\"" {
+<CComment,CNComment>"\"" {
yyextra->stringContext = YY_START;
copyToOutput(yyscanner,yytext,(int)yyleng);
BEGIN(SkipString);
}
*/
-<CComment>. {
+<CComment,CNComment>. {
copyToOutput(yyscanner,yytext,(int)yyleng);
}
<SComment>^[ \t]*{CPPC}"/"{SLASHopt}/\n {
@@ -838,7 +842,7 @@ SLASHopt [/]*
copyToOutput(yyscanner,yytext,(int)yyleng);
BEGIN(yyextra->readLineCtx);
}
-<CComment,ReadLine>[\\@][\\@][~a-z_A-Z][a-z_A-Z0-9]*[ \t]* { // escaped command
+<CComment,CNComment,ReadLine>[\\@][\\@][~a-z_A-Z][a-z_A-Z0-9]*[ \t]* { // escaped command
copyToOutput(yyscanner,yytext,(int)yyleng);
}
<CComment,ReadLine>[\\@]"cond"/[^a-z_A-Z0-9] { // conditional section
diff --git a/src/commentscan.l b/src/commentscan.l
index 23a0471..2bc1b55 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -1479,7 +1479,7 @@ STopt [^\n@\\]*
/* ----- handle arguments of the preformatted block commands ------- */
-<FormatBlock>{CMD}("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"enddot"|"endcode"|"endmsc"|"endvhdlflow")/{NW} { // possible ends
+<FormatBlock>{CMD}("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"enddot"|"endcode"|"endmsc")/{NW} { // possible ends
addOutput(yyscanner,yytext);
if (&yytext[4]==yyextra->blockName) // found end of the block
{
diff --git a/src/configgen.py b/src/configgen.py
index 5c4c39a..b7736c4 100755
--- a/src/configgen.py
+++ b/src/configgen.py
@@ -696,34 +696,35 @@ def main():
print(" static ConfigValues &instance() { static ConfigValues theInstance; return theInstance; }")
for n in elem.childNodes:
if n.nodeType == Node.ELEMENT_NODE:
- if (n.nodeName == "group"):
+ if n.nodeName == "group":
parseGroupMapGetter(n)
for n in elem.childNodes:
if n.nodeType == Node.ELEMENT_NODE:
- if (n.nodeName == "group"):
+ if n.nodeName == "group":
parseGroupMapSetter(n)
print(" void init();")
- print(" struct Info");
- print(" {");
- print(" enum Type { Bool, Int, String, List, Unknown };");
- print(" Info(Type t,bool ConfigValues::*b) : type(t), value(b) {}");
- print(" Info(Type t,int ConfigValues::*i) : type(t), value(i) {}");
- print(" Info(Type t,QCString ConfigValues::*s) : type(t), value(s) {}");
- print(" Info(Type t,StringVector ConfigValues::*l) : type(t), value(l) {}");
- print(" Type type;");
- print(" union Item");
- print(" {");
- print(" Item(bool ConfigValues::*v) : b(v) {}");
- print(" Item(int ConfigValues::*v) : i(v) {}");
- print(" Item(QCString ConfigValues::*v) : s(v) {}");
- print(" Item(StringVector ConfigValues::*v) : l(v) {}");
- print(" bool ConfigValues::*b;");
- print(" int ConfigValues::*i;");
- print(" QCString ConfigValues::*s;");
- print(" StringVector ConfigValues::*l;");
- print(" } value;");
- print(" };");
- print(" const Info *get(const QCString &tag) const;");
+ print(" StringVector fields() const;")
+ print(" struct Info")
+ print(" {")
+ print(" enum Type { Bool, Int, String, List, Unknown };")
+ print(" Info(Type t,bool ConfigValues::*b) : type(t), value(b) {}")
+ print(" Info(Type t,int ConfigValues::*i) : type(t), value(i) {}")
+ print(" Info(Type t,QCString ConfigValues::*s) : type(t), value(s) {}")
+ print(" Info(Type t,StringVector ConfigValues::*l) : type(t), value(l) {}")
+ print(" Type type;")
+ print(" union Item")
+ print(" {")
+ print(" Item(bool ConfigValues::*v) : b(v) {}")
+ print(" Item(int ConfigValues::*v) : i(v) {}")
+ print(" Item(QCString ConfigValues::*v) : s(v) {}")
+ print(" Item(StringVector ConfigValues::*v) : l(v) {}")
+ print(" bool ConfigValues::*b;")
+ print(" int ConfigValues::*i;")
+ print(" QCString ConfigValues::*s;")
+ print(" StringVector ConfigValues::*l;")
+ print(" } value;")
+ print(" };")
+ print(" const Info *get(const QCString &tag) const;")
print(" private:")
for n in elem.childNodes:
if n.nodeType == Node.ELEMENT_NODE:
@@ -765,6 +766,26 @@ def main():
if (n.nodeName == "group"):
parseGroupInit(n)
print("}")
+ print("")
+ print("StringVector ConfigValues::fields() const")
+ print("{")
+ print(" return {");
+ first=True
+ for n in elem.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "group"):
+ for c in n.childNodes:
+ if c.nodeType == Node.ELEMENT_NODE:
+ name = c.getAttribute('id')
+ type = c.getAttribute('type')
+ if type!='obsolete':
+ if not first:
+ print(",")
+ first=False
+ sys.stdout.write(' "'+name+'"')
+ print("")
+ print(" };")
+ print("}")
elif (sys.argv[1] == "-cpp"):
print("/* WARNING: This file is generated!")
print(" * Do not edit this file, but edit config.xml instead and run")
diff --git a/src/context.cpp b/src/context.cpp
index 2ae62a0..6835d98 100644
--- a/src/context.cpp
+++ b/src/context.cpp
@@ -279,6 +279,17 @@ class PropertyMapper
return it!=m_map.end() ? (*it->second)(obj) : TemplateVariant();
}
+ StringVector fields() const
+ {
+ StringVector result;
+ for (const auto &kv : m_map)
+ {
+ result.push_back(kv.first);
+ }
+ std::sort(result.begin(),result.end());
+ return result;
+ }
+
private:
std::unordered_map<std::string,std::unique_ptr<PropertyFuncIntf>> m_map;
};
@@ -364,6 +375,11 @@ TemplateVariant ConfigContext::get(const QCString &name) const
return result;
}
+StringVector ConfigContext::fields() const
+{
+ return ConfigValues::instance().fields();
+}
+
//------------------------------------------------------------------------
//%% struct Doxygen: global information
@@ -379,9 +395,13 @@ class DoxygenContext::Private
{
return dateToString(TRUE);
}
- TemplateVariant maxJaxCodeFile() const
+ TemplateVariant mathJaxCodeFile() const
{
- return m_cache.maxJaxCodeFile;
+ return m_cache.mathJaxCodeFile;
+ }
+ TemplateVariant mathJaxMacros() const
+ {
+ return m_cache.mathJaxMacros;
}
Private()
{
@@ -393,7 +413,9 @@ class DoxygenContext::Private
//%% string date
s_inst.addProperty("date", &Private::date);
//%% string maxJaxCodeFile
- s_inst.addProperty("mathJaxCodeFile", &Private::maxJaxCodeFile);
+ s_inst.addProperty("mathJaxCodeFile", &Private::mathJaxCodeFile);
+ //%% string maxJaxMacros
+ s_inst.addProperty("mathJaxMacros", &Private::mathJaxMacros);
init=TRUE;
}
}
@@ -401,11 +423,19 @@ class DoxygenContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
private:
struct Cachable
{
- Cachable() { maxJaxCodeFile=fileToString(Config_getString(MATHJAX_CODEFILE)); }
- QCString maxJaxCodeFile;
+ Cachable() {
+ mathJaxCodeFile=fileToString(Config_getString(MATHJAX_CODEFILE));
+ mathJaxMacros=HtmlGenerator::getMathJaxMacros();
+ }
+ QCString mathJaxCodeFile;
+ QCString mathJaxMacros;
};
mutable Cachable m_cache;
static PropertyMapper<DoxygenContext::Private> s_inst;
@@ -430,6 +460,11 @@ TemplateVariant DoxygenContext::get(const QCString &n) const
return p->get(n);
}
+StringVector DoxygenContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% struct Translator: translation methods
@@ -1019,6 +1054,10 @@ class TranslateContext::Private
{
return HtmlHelp::getLanguageString();
}
+ TemplateVariant code() const
+ {
+ return theTranslator->trCode();
+ }
Private()
{
static bool init=FALSE;
@@ -1214,6 +1253,8 @@ class TranslateContext::Private
s_inst.addProperty("examplesDescription",&Private::examplesDescription);
//%% string langstring
s_inst.addProperty("langString", &Private::langString);
+ //%% string code
+ s_inst.addProperty("code", &Private::code);
init=TRUE;
}
@@ -1227,6 +1268,10 @@ class TranslateContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
private:
bool m_javaOpt;
bool m_fortranOpt;
@@ -1253,6 +1298,11 @@ TemplateVariant TranslateContext::get(const QCString &n) const
return p->get(n);
}
+StringVector TranslateContext::fields() const
+{
+ return p->fields();
+}
+
static TemplateVariant parseDoc(const Definition *def,const QCString &file,int line,
const QCString &relPath,const QCString &docStr,bool isBrief)
{
@@ -1698,6 +1748,10 @@ class IncludeInfoContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant isLocal() const
{
bool isIDLorJava = m_lang==SrcLangExt_IDL || m_lang==SrcLangExt_Java;
@@ -1749,6 +1803,12 @@ TemplateVariant IncludeInfoContext::get(const QCString &n) const
{
return p->get(n);
}
+
+StringVector IncludeInfoContext::fields() const
+{
+ return p->fields();
+}
+
//%% }
//------------------------------------------------------------------------
@@ -1881,6 +1941,10 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant title() const
{
return TemplateVariant(m_classDef->title());
@@ -2652,6 +2716,11 @@ TemplateVariant ClassContext::get(const QCString &n) const
return p->get(n);
}
+StringVector ClassContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% struct Namespace(Symbol): namespace information
@@ -2698,6 +2767,10 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant title() const
{
return TemplateVariant(m_namespaceDef->title());
@@ -2943,6 +3016,11 @@ TemplateVariant NamespaceContext::get(const QCString &n) const
return p->get(n);
}
+StringVector NamespaceContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% struct File(Symbol): file information
@@ -2999,6 +3077,10 @@ class FileContext::Private : public DefinitionContext<FileContext::Private>
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant title() const
{
return m_fileDef->title();
@@ -3395,6 +3477,11 @@ TemplateVariant FileContext::get(const QCString &n) const
return p->get(n);
}
+StringVector FileContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% struct Dir(Symbol): directory information
@@ -3427,6 +3514,10 @@ class DirContext::Private : public DefinitionContext<DirContext::Private>
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant title() const
{
return TemplateVariant(m_dirDef->shortTitle());
@@ -3584,6 +3675,11 @@ TemplateVariant DirContext::get(const QCString &n) const
return p->get(n);
}
+StringVector DirContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% struct Page(Symbol): page information
@@ -3612,6 +3708,10 @@ class PageContext::Private : public DefinitionContext<PageContext::Private>
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant title() const
{
if (m_isMainPage)
@@ -3717,6 +3817,11 @@ TemplateVariant PageContext::get(const QCString &n) const
return p->get(n);
}
+StringVector PageContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
class TextGeneratorHtml : public TextGeneratorIntf
@@ -4063,6 +4168,10 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant fieldType() const
{
return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->fieldType());
@@ -5164,6 +5273,10 @@ TemplateVariant MemberContext::get(const QCString &n) const
return p->get(n);
}
+StringVector MemberContext::fields() const
+{
+ return p->fields();
+}
//------------------------------------------------------------------------
@@ -5229,6 +5342,10 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private>
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant title() const
{
return TemplateVariant(m_groupDef->groupTitle());
@@ -5675,6 +5792,11 @@ TemplateVariant ModuleContext::get(const QCString &n) const
return p->get(n);
}
+StringVector ModuleContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% list ClassList[Class] : list of classes
@@ -5753,6 +5875,10 @@ class ClassIndexContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant list() const
{
if (!m_cache.classes)
@@ -5840,6 +5966,11 @@ TemplateVariant ClassIndexContext::get(const QCString &n) const
return p->get(n);
}
+StringVector ClassIndexContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
static int computeMaxDepth(const TemplateListIntf *list)
@@ -5945,6 +6076,10 @@ class ClassHierarchyContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant tree() const
{
return m_classTree.get();
@@ -6053,6 +6188,11 @@ TemplateVariant ClassHierarchyContext::get(const QCString &name) const
return p->get(name);
}
+StringVector ClassHierarchyContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% struct NestingNode: node is a nesting relation tree
@@ -6066,6 +6206,7 @@ class NestingNodeContext::Private
: m_parent(parent), m_def(d), m_level(level), m_index(index)
{
m_children.reset(NestingContext::alloc(thisNode,level+1));
+ m_members.reset(NestingContext::alloc(thisNode,level+1));
static bool init=FALSE;
if (!init)
{
@@ -6073,6 +6214,8 @@ class NestingNodeContext::Private
s_inst.addProperty("is_leaf_node",&Private::isLeafNode);
//%% Nesting children: list of nested classes/namespaces
s_inst.addProperty("children",&Private::children);
+ //%% Nesting children: list of nested classes/namespaces
+ s_inst.addProperty("members",&Private::members);
//%% [optional] Class class: class info (if this node represents a class)
s_inst.addProperty("class",&Private::getClass);
//%% [optional] Namespace namespace: namespace info (if this node represents a namespace)
@@ -6085,6 +6228,8 @@ class NestingNodeContext::Private
s_inst.addProperty("page",&Private::getPage);
//%% [optional] Module module: module info (if this node represents a module)
s_inst.addProperty("module",&Private::getModule);
+ //%% [optional] Member member: member info (if this node represents a member)
+ s_inst.addProperty("member",&Private::getMember);
//%% int id
s_inst.addProperty("id",&Private::id);
//%% string level
@@ -6107,11 +6252,16 @@ class NestingNodeContext::Private
addDirFiles(visitedClasses);
addPages(visitedClasses);
addModules(visitedClasses);
+ addMembers(visitedClasses);
}
TemplateVariant get(const QCString &n) const
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant isLeafNode() const
{
return m_children->count()==0;
@@ -6120,6 +6270,10 @@ class NestingNodeContext::Private
{
return m_children.get();
}
+ TemplateVariant members() const
+ {
+ return m_members.get();
+ }
TemplateVariant getClass() const
{
if (!m_cache.classContext && m_def->definitionType()==Definition::TypeClass)
@@ -6210,6 +6364,21 @@ class NestingNodeContext::Private
return TemplateVariant(FALSE);
}
}
+ TemplateVariant getMember() const
+ {
+ if (!m_cache.memberContext && m_def->definitionType()==Definition::TypeMember)
+ {
+ m_cache.memberContext.reset(MemberContext::alloc(toMemberDef(m_def)));
+ }
+ if (m_cache.memberContext)
+ {
+ return m_cache.memberContext.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
TemplateVariant level() const
{
return m_level;
@@ -6272,26 +6441,26 @@ class NestingNodeContext::Private
void addClasses(bool inherit, bool hideSuper,ClassDefSet &visitedClasses)
{
const ClassDef *cd = toClassDef(m_def);
- if (cd && inherit)
+ if (cd)
{
- bool hasChildren = visitedClasses.find(cd)==visitedClasses.end() &&
- !hideSuper && classHasVisibleChildren(cd);
- if (hasChildren)
+ if (inherit)
{
- visitedClasses.insert(cd);
- if (cd->getLanguage()==SrcLangExt_VHDL)
- {
- m_children->addDerivedClasses(cd->baseClasses(),false,visitedClasses);
- }
- else
+ bool hasChildren = visitedClasses.find(cd)==visitedClasses.end() &&
+ !hideSuper && classHasVisibleChildren(cd);
+ if (hasChildren)
{
- m_children->addDerivedClasses(cd->subClasses(),false,visitedClasses);
+ visitedClasses.insert(cd);
+ if (cd->getLanguage()==SrcLangExt_VHDL)
+ {
+ m_children->addDerivedClasses(cd->baseClasses(),false,visitedClasses);
+ }
+ else
+ {
+ m_children->addDerivedClasses(cd->subClasses(),false,visitedClasses);
+ }
}
}
- }
- else
- {
- if (cd)
+ else
{
m_children->addClasses(cd->getClasses(),FALSE,visitedClasses);
}
@@ -6300,13 +6469,16 @@ class NestingNodeContext::Private
void addNamespaces(bool addClasses,ClassDefSet &visitedClasses)
{
const NamespaceDef *nd = toNamespaceDef(m_def);
- if (nd && !nd->getNamespaces().empty())
- {
- m_children->addNamespaces(nd->getNamespaces(),FALSE,addClasses,visitedClasses);
- }
- if (addClasses && nd)
+ if (nd)
{
- m_children->addClasses(nd->getClasses(),FALSE,visitedClasses);
+ if (!nd->getNamespaces().empty())
+ {
+ m_children->addNamespaces(nd->getNamespaces(),FALSE,addClasses,visitedClasses);
+ }
+ if (addClasses)
+ {
+ m_children->addClasses(nd->getClasses(),FALSE,visitedClasses);
+ }
}
}
void addDirFiles(ClassDefSet &visitedClasses)
@@ -6334,10 +6506,53 @@ class NestingNodeContext::Private
m_children->addModules(gd->getSubGroups(),visitedClasses);
}
}
+ void addMembers(ClassDefSet &visitedClasses)
+ {
+ if (m_def->definitionType()==Definition::TypeNamespace)
+ {
+ // add namespace members
+ for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Namespace))
+ {
+ if (lde->kind()==LayoutDocEntry::MemberDef)
+ {
+ const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get();
+ const MemberList *ml = toNamespaceDef(m_def)->getMemberList(lmd->type);
+ m_members->addMembers(ml,visitedClasses);
+ }
+ }
+ }
+ else if (m_def->definitionType()==Definition::TypeClass)
+ {
+ // add class members
+ for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Class))
+ {
+ if (lde->kind()==LayoutDocEntry::MemberDef)
+ {
+ const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get();
+ const MemberList *ml = toClassDef(m_def)->getMemberList(lmd->type);
+ m_members->addMembers(ml,visitedClasses);
+ }
+ }
+ }
+ else if (m_def->definitionType()==Definition::TypeFile)
+ {
+ // add class members
+ for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::File))
+ {
+ if (lde->kind()==LayoutDocEntry::MemberDef)
+ {
+ const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get();
+ const MemberList *ml = toFileDef(m_def)->getMemberList(lmd->type);
+ m_members->addMembers(ml,visitedClasses);
+ }
+ }
+ }
+ }
private:
const NestingNodeContext *m_parent;
const Definition *m_def;
SharedPtr<NestingContext> m_children;
+ SharedPtr<NestingContext> m_members;
int m_level;
int m_index;
struct Cachable
@@ -6348,6 +6563,7 @@ class NestingNodeContext::Private
SharedPtr<FileContext> fileContext;
SharedPtr<PageContext> pageContext;
SharedPtr<ModuleContext> moduleContext;
+ SharedPtr<MemberContext> memberContext;
ScopedPtr<TemplateVariant> brief;
};
mutable Cachable m_cache;
@@ -6375,6 +6591,11 @@ TemplateVariant NestingNodeContext::get(const QCString &n) const
return p->get(n);
}
+StringVector NestingNodeContext::fields() const
+{
+ return p->fields();
+}
+
QCString NestingNodeContext::id() const
{
return p->id().toString();
@@ -6485,7 +6706,8 @@ class NestingContext::Private : public GenericNodeListContext
{
if (fd->getDirDef()==0) // top level file
{
- append(NestingNodeContext::alloc(m_parent,fd.get(),m_index,m_level,FALSE,FALSE,FALSE,visitedClasses));
+ NestingNodeContext *nnc = NestingNodeContext::alloc(m_parent,fd.get(),m_index,m_level,FALSE,FALSE,FALSE,visitedClasses);
+ append(nnc);
m_index++;
}
}
@@ -6495,7 +6717,8 @@ class NestingContext::Private : public GenericNodeListContext
{
for (const auto &fd : fList)
{
- append(NestingNodeContext::alloc(m_parent,fd,m_index,m_level,FALSE,FALSE,FALSE,visitedClasses));
+ NestingNodeContext *nnc=NestingNodeContext::alloc(m_parent,fd,m_index,m_level,FALSE,FALSE,FALSE,visitedClasses);
+ append(nnc);
m_index++;
}
}
@@ -6605,6 +6828,21 @@ class NestingContext::Private : public GenericNodeListContext
}
}
}
+ void addMembers(const MemberList *ml,ClassDefSet &visitedClasses)
+ {
+ if (ml)
+ {
+ for (const auto &md : *ml)
+ {
+ if (md->visibleInIndex())
+ {
+ NestingNodeContext *nnc = NestingNodeContext::alloc(m_parent,md,m_index,m_level+1,TRUE,TRUE,FALSE,visitedClasses);
+ append(nnc);
+ m_index++;
+ }
+ }
+ }
+ }
private:
const NestingNodeContext *m_parent;
@@ -6708,6 +6946,11 @@ void NestingContext::addDerivedClasses(const BaseClassList &bcl,bool hideSuper,C
p->addDerivedClasses(bcl,hideSuper,visitedClasses);
}
+void NestingContext::addMembers(const MemberList *ml,ClassDefSet &visitedClasses)
+{
+ p->addMembers(ml,visitedClasses);
+}
+
//------------------------------------------------------------------------
//%% struct ClassTree: Class nesting relations
@@ -6740,6 +6983,10 @@ class ClassTreeContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant tree() const
{
return m_classTree.get();
@@ -6828,6 +7075,11 @@ TemplateVariant ClassTreeContext::get(const QCString &name) const
return p->get(name);
}
+StringVector ClassTreeContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% list NamespaceList[Namespace] : list of namespaces
@@ -6904,6 +7156,10 @@ class NamespaceTreeContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant tree() const
{
return m_namespaceTree.get();
@@ -6994,6 +7250,12 @@ TemplateVariant NamespaceTreeContext::get(const QCString &name) const
return p->get(name);
}
+StringVector NamespaceTreeContext::fields() const
+{
+ return p->fields();
+}
+
+
//------------------------------------------------------------------------
//%% list FileList[File] : list of files
@@ -7174,6 +7436,10 @@ class FileTreeContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant tree() const
{
return m_dirFileTree.get();
@@ -7249,6 +7515,11 @@ TemplateVariant FileTreeContext::get(const QCString &name) const
return p->get(name);
}
+StringVector FileTreeContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% struct PageTree: tree of related pages
@@ -7282,6 +7553,10 @@ class PageTreeContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant tree() const
{
return m_pageTree.get();
@@ -7357,6 +7632,11 @@ TemplateVariant PageTreeContext::get(const QCString &name) const
return p->get(name);
}
+StringVector PageTreeContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% list PageList[Page]: list of pages
@@ -7524,6 +7804,10 @@ class ModuleTreeContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant tree() const
{
return m_moduleTree.get();
@@ -7599,6 +7883,11 @@ TemplateVariant ModuleTreeContext::get(const QCString &name) const
return p->get(name);
}
+StringVector ModuleTreeContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% struct NavPathElem: list of examples page
@@ -7624,6 +7913,10 @@ class NavPathElemContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant isLinkable() const
{
return m_def->isLinkable();
@@ -7693,6 +7986,10 @@ TemplateVariant NavPathElemContext::get(const QCString &name) const
return p->get(name);
}
+StringVector NavPathElemContext::fields() const
+{
+ return p->fields();
+}
//------------------------------------------------------------------------
@@ -7726,6 +8023,10 @@ class ExampleTreeContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant tree() const
{
return m_exampleTree.get();
@@ -7801,6 +8102,11 @@ TemplateVariant ExampleTreeContext::get(const QCString &name) const
return p->get(name);
}
+StringVector ExampleTreeContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% struct GlobalsIndex: list of examples page
@@ -7835,6 +8141,10 @@ class GlobalsIndexContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
typedef bool (MemberDef::*MemberFunc)() const;
TemplateVariant getMembersFiltered(SharedPtr<TemplateList> &listRef,MemberFunc filter) const
{
@@ -7954,6 +8264,12 @@ TemplateVariant GlobalsIndexContext::get(const QCString &name) const
return p->get(name);
}
+StringVector GlobalsIndexContext::fields() const
+{
+ return p->fields();
+}
+
+
//------------------------------------------------------------------------
//%% struct ClassMembersIndex: list of examples page
@@ -7988,6 +8304,10 @@ class ClassMembersIndexContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
typedef bool (MemberDef::*MemberFunc)() const;
TemplateVariant getMembersFiltered(SharedPtr<TemplateList> &listRef,MemberFunc filter) const
{
@@ -8109,6 +8429,11 @@ TemplateVariant ClassMembersIndexContext::get(const QCString &name) const
return p->get(name);
}
+StringVector ClassMembersIndexContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% struct NamespaceMembersIndex: list of examples page
@@ -8143,6 +8468,10 @@ class NamespaceMembersIndexContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
typedef bool (MemberDef::*MemberFunc)() const;
TemplateVariant getMembersFiltered(SharedPtr<TemplateList> &listRef,MemberFunc filter) const
{
@@ -8261,6 +8590,11 @@ TemplateVariant NamespaceMembersIndexContext::get(const QCString &name) const
return p->get(name);
}
+StringVector NamespaceMembersIndexContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% struct InheritanceGraph: a connected graph representing part of the overall inheritance tree
@@ -8281,6 +8615,10 @@ class InheritanceGraphContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant graph() const
{
TextStream t;
@@ -8322,6 +8660,10 @@ TemplateVariant InheritanceGraphContext::get(const QCString &name) const
return p->get(name);
}
+StringVector InheritanceGraphContext::fields() const
+{
+ return p->fields();
+}
//------------------------------------------------------------------------
@@ -8344,6 +8686,10 @@ class InheritanceNodeContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant getClass() const
{
if (!m_classContext)
@@ -8381,6 +8727,11 @@ TemplateVariant InheritanceNodeContext::get(const QCString &name) const
return p->get(name);
}
+StringVector InheritanceNodeContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% list InheritanceList[InheritanceNode] : list of inherited classes
@@ -8528,6 +8879,10 @@ class MemberInfoContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant protection() const
{
switch (m_memberInfo->prot())
@@ -8592,6 +8947,10 @@ TemplateVariant MemberInfoContext::get(const QCString &name) const
return p->get(name);
}
+StringVector MemberInfoContext::fields() const
+{
+ return p->fields();
+}
//------------------------------------------------------------------------
@@ -8680,6 +9039,10 @@ class MemberGroupInfoContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant members() const
{
if (!m_cache.memberListContext)
@@ -8764,6 +9127,11 @@ TemplateVariant MemberGroupInfoContext::get(const QCString &name) const
return p->get(name);
}
+StringVector MemberGroupInfoContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% list MemberGroupList[MemberGroupInfo] : list of member groups
@@ -8854,6 +9222,10 @@ class MemberListInfoContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant members() const
{
if (!m_cache.memberListContext)
@@ -8936,6 +9308,11 @@ TemplateVariant MemberListInfoContext::get(const QCString &name) const
return p->get(name);
}
+StringVector MemberListInfoContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% struct InheritedMemberInfo: inherited member information
@@ -8961,6 +9338,10 @@ class InheritedMemberInfoContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
virtual ~Private()
{
delete m_memberList;
@@ -9030,6 +9411,11 @@ TemplateVariant InheritedMemberInfoContext::get(const QCString &name) const
return p->get(name);
}
+StringVector InheritedMemberInfoContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% list InheritedMemberList[InheritedMemberInfo] : list of inherited classes
@@ -9193,6 +9579,10 @@ class ArgumentContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant type() const
{
return createLinkedText(m_def,m_relPath,m_argument.type);
@@ -9271,6 +9661,11 @@ TemplateVariant ArgumentContext::get(const QCString &name) const
return p->get(name);
}
+StringVector ArgumentContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% list ArgumentList[Argument] : list of inherited classes
@@ -9360,6 +9755,10 @@ class SymbolContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant fileName() const
{
return m_def->getOutputFileBase();
@@ -9377,61 +9776,82 @@ class SymbolContext::Private
const Definition *prevScope = prev ? prev->getOuterScope() : 0;
const MemberDef *md = toMemberDef(m_def);
bool isFunctionLike = md && (md->isFunction() || md->isSlot() || md->isSignal());
- bool overloadedFunction = isFunctionLike &&
- ((prevScope!=0 && scope==prevScope) || (scope && scope==nextScope));
- QCString prefix;
- if (md) prefix=md->localName();
- if (overloadedFunction) // overloaded member function
- {
- prefix+=md->argsString();
- // show argument list to disambiguate overloaded functions
- }
- else if (md && isFunctionLike) // unique member function
- {
- prefix+="()"; // only to show it is a function
- }
- bool found=FALSE;
+ bool overloadedFunction = ((prevScope!=0 && scope==prevScope) || (scope && scope==nextScope)) &&
+ md && (md->isFunction() || md->isSlot());
+
QCString name;
- if (m_def->definitionType()==Definition::TypeClass)
+ if (prev==0 && next==0) // unique name
{
- name = m_def->displayName();
- found = TRUE;
- }
- else if (m_def->definitionType()==Definition::TypeNamespace)
- {
- name = m_def->displayName();
- found = TRUE;
- }
- else if (scope==0 || scope==Doxygen::globalScope) // in global scope
- {
- if (md)
+ if (scope!=Doxygen::globalScope)
+ {
+ name = scope->name();
+ }
+ else if (md)
{
const FileDef *fd = md->getBodyDef();
if (fd==0) fd = md->getFileDef();
if (fd)
{
- if (!prefix.isEmpty()) prefix+=": ";
- name = prefix + convertToXML(fd->localName());
- found = TRUE;
+ name = fd->localName();
}
}
}
- else if (md && (md->getClassDef() || md->getNamespaceDef()))
- // member in class or namespace scope
- {
- SrcLangExt lang = md->getLanguage();
- name = m_def->getOuterScope()->qualifiedName()
- + getLanguageSpecificSeparator(lang) + prefix;
- found = TRUE;
- }
- else if (scope) // some thing else? -> show scope
- {
- name = prefix + convertToXML(scope->name());
- found = TRUE;
- }
- if (!found) // fallback
+ else
{
- name = prefix + "("+theTranslator->trGlobalNamespace()+")";
+
+ QCString prefix;
+ if (md) prefix=md->localName();
+ if (overloadedFunction) // overloaded member function
+ {
+ prefix+=md->argsString();
+ // show argument list to disambiguate overloaded functions
+ }
+ else if (md && isFunctionLike) // unique member function
+ {
+ prefix+="()"; // only to show it is a function
+ }
+ bool found=FALSE;
+ if (m_def->definitionType()==Definition::TypeClass)
+ {
+ name = m_def->displayName();
+ found = TRUE;
+ }
+ else if (m_def->definitionType()==Definition::TypeNamespace)
+ {
+ name = m_def->displayName();
+ found = TRUE;
+ }
+ else if (scope==0 || scope==Doxygen::globalScope) // in global scope
+ {
+ if (md)
+ {
+ const FileDef *fd = md->getBodyDef();
+ if (fd==0) fd = md->getFileDef();
+ if (fd)
+ {
+ if (!prefix.isEmpty()) prefix+=": ";
+ name = prefix + convertToXML(fd->localName());
+ found = TRUE;
+ }
+ }
+ }
+ else if (md && (md->resolveAlias()->getClassDef() || md->resolveAlias()->getNamespaceDef()))
+ // member in class or namespace scope
+ {
+ SrcLangExt lang = md->getLanguage();
+ name = m_def->getOuterScope()->qualifiedName()
+ + getLanguageSpecificSeparator(lang) + prefix;
+ found = TRUE;
+ }
+ else if (scope) // some thing else? -> show scope
+ {
+ name = prefix + convertToXML(scope->name());
+ found = TRUE;
+ }
+ if (!found) // fallback
+ {
+ name = prefix + "("+theTranslator->trGlobalNamespace()+")";
+ }
}
return name;
}
@@ -9465,6 +9885,11 @@ TemplateVariant SymbolContext::get(const QCString &name) const
return p->get(name);
}
+StringVector SymbolContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% list SymbolList[Symbol] : list of search symbols with the same name
@@ -9537,6 +9962,10 @@ class SymbolGroupContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant id() const
{
return searchId(*m_start);
@@ -9584,6 +10013,11 @@ TemplateVariant SymbolGroupContext::get(const QCString &name) const
return p->get(name);
}
+StringVector SymbolGroupContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% list SymbolGroupList[SymbolGroup] : list of search groups one per by name
@@ -9600,7 +10034,10 @@ class SymbolGroupListContext::Private : public GenericNodeListContext
QCString name = searchName(*it);
if (name!=lastName)
{
- append(SymbolGroupContext::alloc(it_begin,it));
+ if (it!=it_begin)
+ {
+ append(SymbolGroupContext::alloc(it_begin,it));
+ }
it_begin = it;
lastName = name;
}
@@ -9664,6 +10101,10 @@ class SymbolIndexContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant name() const
{
return m_name;
@@ -9711,6 +10152,11 @@ TemplateVariant SymbolIndexContext::get(const QCString &name) const
return p->get(name);
}
+StringVector SymbolIndexContext::fields() const
+{
+ return p->fields();
+}
+
//------------------------------------------------------------------------
//%% list SymbolIndices[SymbolIndex] : list of search indices one per by type
@@ -9775,6 +10221,10 @@ class SearchIndexContext::Private
{
return s_inst.get(this,n);
}
+ StringVector fields() const
+ {
+ return s_inst.fields();
+ }
TemplateVariant name() const
{
return m_info.name;
@@ -9820,6 +10270,12 @@ TemplateVariant SearchIndexContext::get(const QCString &name) const
return p->get(name);
}
+StringVector SearchIndexContext::fields() const
+{
+ return p->fields();
+}
+
+
//------------------------------------------------------------------------
//%% list SearchIndices[SearchIndex] : list of search indices one per by type
diff --git a/src/context.h b/src/context.h
index 1fb934e..bff4903 100644
--- a/src/context.h
+++ b/src/context.h
@@ -135,6 +135,7 @@ class ConfigContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -154,6 +155,7 @@ class DoxygenContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -173,6 +175,7 @@ class TranslateContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -217,6 +220,7 @@ class IncludeInfoContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -259,6 +263,7 @@ class ClassContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -278,6 +283,7 @@ class NamespaceContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -297,6 +303,7 @@ class FileContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -315,6 +322,7 @@ class DirContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -335,6 +343,7 @@ class PageContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -354,6 +363,7 @@ class MemberContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -374,6 +384,7 @@ class ModuleContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -414,6 +425,7 @@ class ClassIndexContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -434,6 +446,7 @@ class InheritanceGraphContext : public RefCountedContext, public TemplateStructI
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -454,6 +467,7 @@ class ClassInheritanceNodeContext : public RefCountedContext, public TemplateStr
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -496,6 +510,7 @@ class ClassHierarchyContext : public RefCountedContext, public TemplateStructInt
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -520,6 +535,7 @@ class NestingNodeContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -562,6 +578,7 @@ class NestingContext : public RefCountedContext, public TemplateListIntf
void addModules(const GroupList &modules,ClassDefSet &visitedClasses);
void addClassHierarchy(const ClassLinkedMap &clLinkedMap,ClassDefSet &visitedClasses);
void addDerivedClasses(const BaseClassList &bcl,bool hideSuper,ClassDefSet &visitedClasses);
+ void addMembers(const MemberList *ml,ClassDefSet &visitedClasses);
private:
NestingContext(const NestingNodeContext *parent,int level);
@@ -579,6 +596,7 @@ class ClassTreeContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -619,6 +637,7 @@ class NamespaceTreeContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -680,6 +699,7 @@ class FileTreeContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -722,6 +742,7 @@ class PageTreeContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -741,6 +762,7 @@ class ModuleNodeContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -784,6 +806,7 @@ class ModuleTreeContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -825,6 +848,7 @@ class ExampleTreeContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -844,6 +868,7 @@ class GlobalsIndexContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -863,6 +888,7 @@ class ClassMembersIndexContext : public RefCountedContext, public TemplateStruct
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -882,6 +908,7 @@ class NamespaceMembersIndexContext : public RefCountedContext, public TemplateSt
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -901,6 +928,7 @@ class NavPathElemContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -922,6 +950,7 @@ class InheritanceNodeContext : public RefCountedContext, public TemplateStructIn
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -992,6 +1021,7 @@ class MemberGroupInfoContext : public RefCountedContext, public TemplateStructIn
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -1043,6 +1073,7 @@ class MemberListInfoContext : public RefCountedContext, public TemplateStructInt
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -1064,6 +1095,7 @@ class MemberInfoContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -1084,6 +1116,7 @@ class InheritedMemberInfoContext : public RefCountedContext, public TemplateStru
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -1148,6 +1181,7 @@ class ArgumentContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -1192,6 +1226,7 @@ class SymbolContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -1237,6 +1272,7 @@ class SymbolGroupContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -1281,6 +1317,7 @@ class SymbolIndexContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
@@ -1323,6 +1360,7 @@ class SearchIndexContext : public RefCountedContext, public TemplateStructIntf
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
diff --git a/src/dirdef.cpp b/src/dirdef.cpp
index 1814b51..f4354a4 100644
--- a/src/dirdef.cpp
+++ b/src/dirdef.cpp
@@ -341,7 +341,7 @@ void DirDefImpl::writeSubDirList(OutputList &ol)
if (dd->hasDocumentation() || dd->getFiles().empty())
{
ol.startMemberDeclaration();
- ol.startMemberItem(dd->getOutputFileBase(),0);
+ ol.startMemberItem(dd->anchor(),0);
ol.parseText(theTranslator->trDir(FALSE,TRUE)+" ");
ol.insertMemberAlign();
ol.writeObjectLink(dd->getReference(),dd->getOutputFileBase(),QCString(),dd->shortName());
@@ -359,7 +359,7 @@ void DirDefImpl::writeSubDirList(OutputList &ol)
);
ol.endMemberDescription();
}
- ol.endMemberDeclaration(QCString(),QCString());
+ ol.endMemberDeclaration(dd->anchor(),QCString());
}
}
@@ -390,7 +390,7 @@ void DirDefImpl::writeFileList(OutputList &ol)
if (fd->hasDocumentation())
{
ol.startMemberDeclaration();
- ol.startMemberItem(fd->getOutputFileBase(),0);
+ ol.startMemberItem(fd->anchor(),0);
ol.docify(theTranslator->trFile(FALSE,TRUE)+" ");
ol.insertMemberAlign();
if (fd->isLinkable())
@@ -429,7 +429,7 @@ void DirDefImpl::writeFileList(OutputList &ol)
);
ol.endMemberDescription();
}
- ol.endMemberDeclaration(QCString(),QCString());
+ ol.endMemberDeclaration(fd->anchor(),QCString());
}
}
ol.endMemberList();
diff --git a/src/docparser.cpp b/src/docparser.cpp
index 331355f..4e316a8 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -6771,6 +6771,7 @@ reparsetoken:
}
else
{
+ m_children.push_back(std::make_unique<DocWord>(this,g_token->name));
warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unsupported symbol %s found",
qPrint(g_token->name));
}
diff --git a/src/docparser.h b/src/docparser.h
index 2117cbb..f256c56 100644
--- a/src/docparser.h
+++ b/src/docparser.h
@@ -642,7 +642,11 @@ class DocFormula : public DocNode
QCString relPath() const { return m_relPath; }
int id() const { return m_id; }
void accept(DocVisitor *v) override { v->visit(this); }
- bool isInline() { return m_text.length()>1 ? !(m_text.at(0)=='\\' && (m_text.at(1)=='{' || m_text.at(1)=='[')): TRUE; }
+ bool isInline() {
+ if (m_text.length()>1 && m_text.at(0)=='\\' && m_text.at(1)=='[') return false;
+ if (m_text.length()>7 && m_text.startsWith("\\begin{")) return false;
+ return true;
+ }
private:
QCString m_name;
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 51fcd16..b9cee8d 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -741,7 +741,7 @@ static Definition *buildScopeFromQualifiedName(const QCString &name_,SrcLangExt
else if (nd==0 && cd==0 && fullScope.find('<')==-1) // scope is not known and could be a namespace!
{
// introduce bogus namespace
- //printf("++ adding dummy namespace %s to %s tagInfo=%p\n",qPrint(nsName),qPrint(prevScope->name()),tagInfo);
+ //printf("++ adding dummy namespace %s to %s tagInfo=%p\n",qPrint(nsName),qPrint(prevScope->name()),(void*)tagInfo);
NamespaceDefMutable *newNd=
toNamespaceDefMutable(
Doxygen::namespaceLinkedMap->add(fullScope,
@@ -1686,6 +1686,11 @@ static void buildNamespaceList(const Entry *root)
// file definition containing the namespace nd
FileDef *fd=root->fileDef();
+ if (nd->isArtificial())
+ {
+ nd->setArtificial(FALSE); // found namespace explicitly, so cannot be artificial
+ nd->setDefFile(root->fileName,root->startLine,root->startColumn);
+ }
// insert the namespace in the file definition
if (fd) fd->insertNamespace(nd);
addNamespaceToGroups(root,nd);
@@ -1971,15 +1976,16 @@ static void buildListOfUsingDecls(const Entry *root)
}
-static void findUsingDeclarations(const Entry *root)
+static void findUsingDeclarations(const Entry *root,bool filterPythonPackages)
{
if (root->section==Entry::USINGDECL_SEC &&
- !(root->parent()->section&Entry::COMPOUND_MASK) // not a class/struct member
+ !(root->parent()->section&Entry::COMPOUND_MASK) && // not a class/struct member
+ (!filterPythonPackages || (root->lang==SrcLangExt_Python && root->fileName.endsWith("__init__.py")))
)
{
//printf("Found using declaration %s at line %d of %s inside section %x\n",
// qPrint(root->name),root->startLine,qPrint(root->fileName),
- // rootNav->parent()->section());
+ // root->parent()->section);
if (!root->name.isEmpty())
{
ClassDefMutable *usingCd = 0;
@@ -2018,7 +2024,7 @@ static void findUsingDeclarations(const Entry *root)
usingCd = toClassDefMutable(Doxygen::hiddenClassLinkedMap->find(name)); // check if it is already hidden
}
- //printf("%s -> %p\n",qPrint(root->name),usingCd);
+ //printf("%s -> %p\n",qPrint(root->name),(void*)usingCd);
if (usingCd==0) // definition not in the input => add an artificial class
{
Debug::print(Debug::Classes,0," New using class '%s' (sec=0x%08x)! #tArgLists=%d\n",
@@ -2054,7 +2060,7 @@ static void findUsingDeclarations(const Entry *root)
}
}
}
- for (const auto &e : root->children()) findUsingDeclarations(e.get());
+ for (const auto &e : root->children()) findUsingDeclarations(e.get(),filterPythonPackages);
}
//----------------------------------------------------------------------
@@ -7668,6 +7674,7 @@ static void computeMemberRelations()
// qPrint(argListToString(mdAl))
// );
if (
+ bmd->getLanguage()==SrcLangExt_Python ||
matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),&bmdAl,
md->getOuterScope(), md->getFileDef(), &mdAl,
TRUE
@@ -9842,7 +9849,6 @@ static std::string resolveSymlink(const std::string &path)
return Dir::cleanDirPath(result.str());
}
-static std::mutex g_pathsVisitedMutex;
static StringUnorderedSet g_pathsVisited(1009);
//----------------------------------------------------------------------------
@@ -9869,15 +9875,24 @@ static void readDir(FileInfo *fi,
{
paths->insert(dirName);
}
+ //printf("%s isSymLink()=%d\n",qPrint(dirName),fi->isSymLink());
if (fi->isSymLink())
{
dirName = resolveSymlink(dirName);
- if (dirName.empty()) return; // recursive symlink
+ if (dirName.empty())
+ {
+ //printf("RECURSIVE SYMLINK: %s\n",qPrint(dirName));
+ return; // recursive symlink
+ }
+ }
- std::lock_guard<std::mutex> lock(g_pathsVisitedMutex);
- if (g_pathsVisited.find(dirName)!=g_pathsVisited.end()) return; // already visited path
- g_pathsVisited.insert(dirName);
+ if (g_pathsVisited.find(dirName)!=g_pathsVisited.end())
+ {
+ //printf("PATH ALREADY VISITED: %s\n",qPrint(dirName));
+ return; // already visited path
}
+ g_pathsVisited.insert(dirName);
+
Dir dir(dirName);
msg("Searching for files in directory %s\n", qPrint(fi->absFilePath()));
//printf("killSet=%p count=%d\n",killSet,killSet ? (int)killSet->count() : -1);
@@ -9930,6 +9945,13 @@ static void readDir(FileInfo *fi,
}
}
}
+ if (resultList)
+ {
+ // sort the resulting list to make the order platform independent.
+ std::sort(resultList->begin(),
+ resultList->end(),
+ [](const auto &f1,const auto &f2) { return qstricmp(f1.c_str(),f2.c_str())<0; });
+ }
}
@@ -9954,6 +9976,8 @@ void readFileOrDirectory(const QCString &s,
// strip trailing slashes
if (s.isEmpty()) return;
+ g_pathsVisited.clear();
+
FileInfo fi(s.str());
//printf("readFileOrDirectory(%s)\n",s);
{
@@ -11510,7 +11534,8 @@ void parseInput()
g_s.begin("Searching for members imported via using declarations...\n");
// this should be after buildTypedefList in order to properly import
// used typedefs
- findUsingDeclarations(root.get());
+ findUsingDeclarations(root.get(),TRUE); // do for python packages first
+ findUsingDeclarations(root.get(),FALSE); // then the rest
g_s.end();
g_s.begin("Searching for included using directives...\n");
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
index e4ec0d6..cfc1b91 100644
--- a/src/htmldocvisitor.cpp
+++ b/src/htmldocvisitor.cpp
@@ -1266,7 +1266,12 @@ void HtmlDocVisitor::visitPre(DocPara *p)
//printf(" needsTag=%d\n",needsTag);
// write the paragraph tag (if needed)
if (needsTag)
- m_t << "<p class=\"" << contexts[t] << "\"" << htmlAttribsToString(p->attribs()) << ">";
+ {
+ if (strlen(contexts[t]))
+ m_t << "<p class=\"" << contexts[t] << "\"" << htmlAttribsToString(p->attribs()) << ">";
+ else
+ m_t << "<p " << htmlAttribsToString(p->attribs()) << ">";
+ }
}
void HtmlDocVisitor::visitPost(DocPara *p)
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index ad8782b..86825e4 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -449,17 +449,25 @@ static QCString substituteHtmlKeywords(const QCString &str,
if (mathJaxVersion == "MathJax_3")
{
- mathJaxJs += "<script>\n"
- " window.MathJax = {\n"
- " options: {\n"
- " ignoreHtmlClass: 'tex2jax_ignore',\n"
- " processHtmlClass: 'tex2jax_process'\n"
- " },\n";
+ mathJaxJs += "<script src=\"https://polyfill.io/v3/polyfill.min.js?features=es6\"></script>\n"
+ "<script type=\"text/javascript\">\n"
+ "window.MathJax = {\n"
+ " options: {\n"
+ " ignoreHtmlClass: 'tex2jax_ignore',\n"
+ " processHtmlClass: 'tex2jax_process'\n"
+ " }";
const StringVector &mathJaxExtensions = Config_getList(MATHJAX_EXTENSIONS);
if (!mathJaxExtensions.empty() || !g_latex_macro.isEmpty())
{
- mathJaxJs+= " tex: {\n"
- " packages: ['base'";
+ mathJaxJs+= ",\n"
+ " tex: {\n"
+ " macros: {";
+ if (!g_latex_macro.isEmpty())
+ {
+ mathJaxJs += g_latex_macro+" ";
+ }
+ mathJaxJs+="},\n"
+ " packages: ['base','configmacros'";
if (!g_latex_macro.isEmpty())
{
mathJaxJs+= ",'newcommand'";
@@ -469,49 +477,30 @@ static QCString substituteHtmlKeywords(const QCString &str,
mathJaxJs+= ",'"+QCString(s.c_str())+"'";
}
mathJaxJs += "]\n"
- " },\n"
- " tex: {\n"
- " macros: {}\n"
- " }\n";
+ " }\n";
}
- mathJaxJs += " };\n";
- mathJaxJs += "</script>\n";
-
- if (!g_latex_macro.isEmpty())
+ else
{
- mathJaxJs += "<script>\n"
- " Object.assign(MathJax.tex.macros, {\n";
- mathJaxJs += g_latex_macro;
- mathJaxJs += "\n"
- " });\n"
- "</script>\n";
+ mathJaxJs += "\n";
}
-
+ mathJaxJs += "};\n";
// MATHJAX_CODEFILE
if (!g_mathjax_code.isEmpty())
{
- mathJaxJs += "<script>\n";
mathJaxJs += g_mathjax_code;
mathJaxJs += "\n";
- mathJaxJs += "</script>\n";
}
+ mathJaxJs += "</script>\n";
-
- mathJaxJs += "<script type=\"text/javascript\" id=\"MathJax-script\" async=\"async\" src=\"" + path;
- if (mathJaxFormat == "chtml")
- {
- mathJaxJs += "es5/tex-chtml.js\"></script>\n" ;
- }
- else if (mathJaxFormat == "SVG")
- {
- mathJaxJs += "es5/tex-svg.js\"></script>\n" ;
- }
+ mathJaxJs += "<script type=\"text/javascript\" id=\"MathJax-script\" async=\"async\" src=\"" +
+ path + "es5/tex-" + mathJaxFormat.lower() + ".js\">";
+ mathJaxJs+="</script>\n";
}
- else
+ else // MathJax v2
{
mathJaxJs = "<script type=\"text/x-mathjax-config\">\n"
- " MathJax.Hub.Config({\n"
- " extensions: [\"tex2jax.js\"";
+ "MathJax.Hub.Config({\n"
+ " extensions: [\"tex2jax.js\"";
const StringVector &mathJaxExtensions = Config_getList(MATHJAX_EXTENSIONS);
for (const auto &s : mathJaxExtensions)
{
@@ -522,25 +511,21 @@ static QCString substituteHtmlKeywords(const QCString &str,
mathJaxFormat = "HTML-CSS";
}
mathJaxJs += "],\n"
- " jax: [\"input/TeX\",\"output/"+mathJaxFormat+"\"],\n"
- "});\n";
+ " jax: [\"input/TeX\",\"output/"+mathJaxFormat+"\"],\n";
+ if (!g_latex_macro.isEmpty())
+ {
+ mathJaxJs += " TeX: { Macros: {\n";
+ mathJaxJs += g_latex_macro;
+ mathJaxJs += "\n"
+ " } }\n";
+ }
+ mathJaxJs += "});\n";
if (!g_mathjax_code.isEmpty())
{
mathJaxJs += g_mathjax_code;
mathJaxJs += "\n";
}
mathJaxJs += "</script>\n";
- if (!g_latex_macro.isEmpty())
- {
- mathJaxJs += "<script type=\"text/x-mathjax-config\">\n"
- " MathJax.Hub.Config({\n"
- " TeX: { Macros: {\n";
- mathJaxJs += g_latex_macro;
- mathJaxJs += "\n"
- " } }\n"
- "});\n"
- "</script>\n";
- }
mathJaxJs += "<script type=\"text/javascript\" async=\"async\" src=\"" + path + "MathJax.js\"></script>\n";
}
}
@@ -999,13 +984,7 @@ void HtmlGenerator::init()
t << mgr.getAsString("dynsections.js");
if (Config_getBool(SOURCE_BROWSER) && Config_getBool(SOURCE_TOOLTIPS))
{
- t <<
- "\n$(document).ready(function() {\n"
- " $('.code,.codeRef').each(function() {\n"
- " $(this).data('powertip',$('#a'+$(this).attr('href').replace(/.*\\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html());\n"
- " $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true });\n"
- " });\n"
- "});\n";
+ t << mgr.getAsString("dynsections_tooltips.js");
}
}
}
@@ -2501,7 +2480,7 @@ static void writeDefaultQuickLinks(TextStream &t,bool compact,
t << "<script type=\"text/javascript\" src=\"" << relPath << "menudata.js\"></script>\n";
t << "<script type=\"text/javascript\" src=\"" << relPath << "menu.js\"></script>\n";
t << "<script type=\"text/javascript\">\n";
- t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */\n";
+ t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */\n";
t << "$(function() {\n";
t << " initMenu('" << relPath << "',"
<< (searchEngine?"true":"false") << ","
@@ -2516,14 +2495,13 @@ static void writeDefaultQuickLinks(TextStream &t,bool compact,
}
else
{
- t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */\n";
t << " $(document).ready(function() {\n"
<< " if ($('.searchresults').length > 0) { searchBox.DOMSearchField().focus(); }\n"
<< " });\n";
}
}
t << "});\n";
- t << "/* @license-end */";
+ t << "/* @license-end */\n";
t << "</script>\n";
t << "<div id=\"main-nav\"></div>\n";
}
@@ -2894,14 +2872,14 @@ void HtmlGenerator::startHeaderSection()
void HtmlGenerator::startTitleHead(const QCString &)
{
- m_t << " <div class=\"headertitle\">\n";
+ m_t << " <div class=\"headertitle\">";
startTitle();
}
void HtmlGenerator::endTitleHead(const QCString &,const QCString &)
{
endTitle();
- m_t << " </div>\n";
+ m_t << "</div>\n";
}
void HtmlGenerator::endHeaderSection()
@@ -3074,3 +3052,8 @@ void HtmlGenerator::addWord(const QCString &word,bool hiPriority)
Doxygen::searchIndex->addWord(word,hiPriority);
}
}
+
+QCString HtmlGenerator::getMathJaxMacros()
+{
+ return getConvertLatexMacro();
+}
diff --git a/src/htmlgen.h b/src/htmlgen.h
index 845f259..c66e622 100644
--- a/src/htmlgen.h
+++ b/src/htmlgen.h
@@ -83,6 +83,7 @@ class HtmlGenerator : public OutputGenerator
static void writeExternalSearchPage();
static QCString writeLogoAsString(const QCString &path);
static QCString writeSplitBarAsString(const QCString &name,const QCString &relpath);
+ static QCString getMathJaxMacros();
// ---- CodeOutputInterface
void codify(const QCString &text)
diff --git a/src/index.cpp b/src/index.cpp
index 99942f1..de50cc5 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -289,18 +289,6 @@ void endFileWithNavPath(const Definition *d,OutputList &ol)
//----------------------------------------------------------------------
-static bool memberVisibleInIndex(const MemberDef *md)
-{
- bool isAnonymous = md->isAnonymous();
- bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
- bool extractStatic = Config_getBool(EXTRACT_STATIC);
- return (!isAnonymous &&
- (!hideUndocMembers || md->hasDocumentation()) &&
- (!md->isStatic() || extractStatic) &&
- md->isLinkable()
- );
-}
-
static void writeMemberToIndex(const Definition *def,const MemberDef *md,bool addToIndex)
{
bool isAnonymous = md->isAnonymous();
@@ -388,7 +376,7 @@ void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part,
{
for (const auto &md : *ml)
{
- if (memberVisibleInIndex(md))
+ if (md->visibleInIndex())
{
writeMemberToIndex(def,md,addToIndex);
}
@@ -1611,7 +1599,7 @@ static int countVisibleMembers(const NamespaceDef *nd)
{
for (const auto &md : *ml)
{
- if (memberVisibleInIndex(md))
+ if (md->visibleInIndex())
{
count++;
}
@@ -1634,8 +1622,8 @@ static void writeNamespaceMembers(const NamespaceDef *nd,bool addToIndex)
{
for (const auto &md : *ml)
{
- //printf(" member %s visible=%d\n",qPrint(md->name()),memberVisibleInIndex(md));
- if (memberVisibleInIndex(md))
+ //printf(" member %s visible=%d\n",qPrint(md->name()),md->visibleInIndex());
+ if (md->visibleInIndex())
{
writeMemberToIndex(nd,md,addToIndex);
}
@@ -2180,7 +2168,9 @@ static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct
// write character heading
ol.writeString("<dt class=\"alphachar\">");
QCString s = letterToLabel(cl.first.c_str());
- ol.writeString("<a name=\"letter_");
+ ol.writeString("<a id=\"letter_");
+ ol.writeString(s);
+ ol.writeString("\" name=\"letter_");
ol.writeString(s);
ol.writeString("\">");
ol.writeString(cl.first.c_str());
@@ -2511,10 +2501,10 @@ static void writeClassLinkForMember(OutputList &ol,const MemberDef *md,const QCS
const ClassDef *cd=md->getClassDef();
if ( cd && prevClassName!=cd->displayName())
{
- ol.docify(separator);
+ ol.writeString(separator);
ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
cd->displayName());
- ol.writeString("\n");
+ //ol.writeString("\n");
prevClassName = cd->displayName();
}
}
@@ -2525,10 +2515,10 @@ static void writeFileLinkForMember(OutputList &ol,const MemberDef *md,const QCSt
const FileDef *fd=md->getFileDef();
if (fd && prevFileName!=fd->name())
{
- ol.docify(separator);
+ ol.writeString(separator);
ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
fd->name());
- ol.writeString("\n");
+ //ol.writeString("\n");
prevFileName = fd->name();
}
}
@@ -2539,10 +2529,10 @@ static void writeNamespaceLinkForMember(OutputList &ol,const MemberDef *md,const
const NamespaceDef *nd=md->getNamespaceDef();
if (nd && prevNamespaceName!=nd->displayName())
{
- ol.docify(separator);
+ ol.writeString(separator);
ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
nd->displayName());
- ol.writeString("\n");
+ //ol.writeString("\n");
prevNamespaceName = nd->displayName();
}
}
@@ -2625,11 +2615,11 @@ static void writeMemberList(OutputList &ol,bool useSections,const std::string &p
firstItem=FALSE;
ol.docify(name);
if (isFunc) ol.docify("()");
- ol.writeString("\n");
+ //ol.writeString("\n");
// link to class
prevDefName="";
- sep = ": ";
+ sep = "&#160;:&#160;";
prevName = name.data()+startIndex;
}
else // same entry
@@ -3512,7 +3502,7 @@ static void writeExampleIndex(OutputList &ol)
}
}
ol.endItemListItem();
- ol.writeString("\n");
+ //ol.writeString("\n");
}
ol.endItemList();
diff --git a/src/lexcode.l b/src/lexcode.l
index 59b05b7..7400bc9 100644
--- a/src/lexcode.l
+++ b/src/lexcode.l
@@ -727,10 +727,18 @@ NONLopt [^\n]*
<DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
yyextra->CCodeBuffer += yytext;
yyextra->docBlockName=&yytext[1];
+ if (yyextra->docBlockName.at(1)=='[')
+ {
+ yyextra->docBlockName.at(1)=']';
+ }
if (yyextra->docBlockName.at(1)=='{')
{
yyextra->docBlockName.at(1)='}';
}
+ if (yyextra->docBlockName.at(1)=='(')
+ {
+ yyextra->docBlockName.at(1)=')';
+ }
yyextra->fencedSize=0;
yyextra->nestedComment=FALSE;
BEGIN(DocCopyBlock);
@@ -742,7 +750,14 @@ NONLopt [^\n]*
yyextra->nestedComment=FALSE;
BEGIN(DocCopyBlock);
}
-<DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
+<DocBlock>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim type command (which could contain nested comments!)
+ yyextra->CCodeBuffer += yytext;
+ yyextra->docBlockName="uml";
+ yyextra->fencedSize=0;
+ yyextra->nestedComment=FALSE;
+ BEGIN(DocCopyBlock);
+ }
+<DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"msc"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
yyextra->CCodeBuffer += yytext;
yyextra->docBlockName=&yytext[1];
yyextra->fencedSize=0;
@@ -796,9 +811,12 @@ NONLopt [^\n]*
}
<DocCopyBlock>[\\@]("f$"|"f]"|"f}"|"f)") {
yyextra->CCodeBuffer += yytext;
- BEGIN(DocBlock);
+ if (yyextra->docBlockName==&yytext[1])
+ {
+ BEGIN(DocBlock);
+ }
}
-<DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
+<DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"enduml"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
yyextra->CCodeBuffer += yytext;
if (&yytext[4]==yyextra->docBlockName)
{
diff --git a/src/lexscanner.l b/src/lexscanner.l
index 2b6b3a0..b02bf8e 100644
--- a/src/lexscanner.l
+++ b/src/lexscanner.l
@@ -709,10 +709,18 @@ NONLopt [^\n]*
<DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
yyextra->cCodeBuffer += yytext;
yyextra->docBlockName=&yytext[1];
+ if (yyextra->docBlockName.at(1)=='[')
+ {
+ yyextra->docBlockName.at(1)=']';
+ }
if (yyextra->docBlockName.at(1)=='{')
{
yyextra->docBlockName.at(1)='}';
}
+ if (yyextra->docBlockName.at(1)=='(')
+ {
+ yyextra->docBlockName.at(1)=')';
+ }
yyextra->fencedSize=0;
yyextra->nestedComment=FALSE;
BEGIN(DocCopyBlock);
@@ -724,7 +732,14 @@ NONLopt [^\n]*
yyextra->nestedComment=FALSE;
BEGIN(DocCopyBlock);
}
-<DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
+<DocBlock>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim type command (which could contain nested comments!)
+ yyextra->cCodeBuffer += yytext;
+ yyextra->docBlockName="uml";
+ yyextra->fencedSize=0;
+ yyextra->nestedComment=FALSE;
+ BEGIN(DocCopyBlock);
+ }
+<DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"msc"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
yyextra->cCodeBuffer += yytext;
yyextra->docBlockName=&yytext[1];
yyextra->fencedSize=0;
@@ -777,11 +792,14 @@ NONLopt [^\n]*
}
<DocCopyBlock>[\\@]("f$"|"f]"|"f}"|"f)") {
yyextra->cCodeBuffer += yytext;
- BEGIN(DocBlock);
+ if (yyextra->docBlockName==&yytext[1])
+ {
+ BEGIN(DocBlock);
+ }
}
-<DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
+<DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"enduml"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
yyextra->cCodeBuffer += yytext;
- if (&yytext[4]==yyextra->docBlockName)
+ if (yyextra->docBlockName==&yytext[4])
{
BEGIN(DocBlock);
}
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index af05535..7133641 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -321,6 +321,7 @@ class MemberDefImpl : public DefinitionMixin<MemberDefMutable>
virtual void writeTagFile(TextStream &) const;
virtual void warnIfUndocumented() const;
virtual void warnIfUndocumentedParams() const;
+ virtual bool visibleInIndex() const;
virtual void detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const;
virtual MemberDefMutable *createTemplateInstanceMember(const ArgumentList &formalArgs,
const std::unique_ptr<ArgumentList> &actualArgs) const;
@@ -744,6 +745,8 @@ class MemberDefAliasImpl : public DefinitionAliasMixin<MemberDef>
{ return getMdAlias()->getDeclColumn(); }
virtual QCString requiresClause() const
{ return getMdAlias()->requiresClause(); }
+ virtual bool visibleInIndex() const
+ { return getMdAlias()->visibleInIndex(); }
virtual void warnIfUndocumented() const {}
virtual void warnIfUndocumentedParams() const {}
@@ -3844,6 +3847,18 @@ void MemberDefImpl::warnIfUndocumented() const
warnIfUndocumentedParams();
}
}
+
+bool MemberDefImpl::visibleInIndex() const
+{
+ bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
+ bool extractStatic = Config_getBool(EXTRACT_STATIC);
+ return (!isAnonymous() &&
+ (!hideUndocMembers || hasDocumentation()) &&
+ (!isStatic() || extractStatic) &&
+ isLinkable()
+ );
+}
+
static QCString stripTrailingReturn(const QCString &trailRet)
{
QCString ret = trailRet;
diff --git a/src/memberdef.h b/src/memberdef.h
index 1d1e744..ca745a0 100644
--- a/src/memberdef.h
+++ b/src/memberdef.h
@@ -285,9 +285,11 @@ class MemberDef : public Definition
virtual void detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const = 0;
virtual void warnIfUndocumented() const = 0;
virtual void warnIfUndocumentedParams() const = 0;
+ virtual bool visibleInIndex() const = 0;
// TODO: this is not a getter, should be passed at construction
virtual void setMemberGroup(MemberGroup *grp) = 0;
+
};
class MemberDefMutable : public DefinitionMutable, public MemberDef
diff --git a/src/pre.l b/src/pre.l
index 7b48ca7..3e9e1df 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -3241,48 +3241,32 @@ static void initPredefined(yyscan_t yyscanner,const QCString &fileName)
) // predefined function macro definition
{
static const reg::Ex reId(R"(\a\w*)");
- reg::Iterator end;
- bool varArgs = false;
- int count = 0;
std::map<std::string,int> argMap;
- if (ds.substr(i_obrace+1,i_cbrace-i_obrace-1)=="...")
+ std::string args = ds.substr(i_obrace+1,i_cbrace-i_obrace-1); // part between ( and )
+ bool hasVarArgs = args.find("...")!=std::string::npos;
+ //printf("predefined function macro '%s'\n",ds.c_str());
+ int count = 0;
+ reg::Iterator arg_it(args,reId,0);
+ reg::Iterator arg_end;
+ // gather the formal arguments in a dictionary
+ for (; arg_it!=arg_end; ++arg_it)
{
- varArgs = true;
- argMap.emplace("__VA_ARGS__",count);
- count++;
+ argMap.emplace(arg_it->str(),count++);
}
- else
+ if (hasVarArgs) // add the variable argument if present
{
- size_t i=i_obrace+1;
- //printf("predefined function macro '%s'\n",ds.c_str());
- reg::Iterator it(ds,reId,i);
- // gather the formal arguments in a dictionary
- while (i<i_cbrace && it!=end)
- {
- const auto &match = *it;
- size_t pi = match.position();
- size_t l = match.length();
- if (l>0) // see bug375037
- {
- argMap.emplace(match.str(),count);
- count++;
- i=pi+l;
- }
- else
- {
- i++;
- }
- ++it;
- }
+ argMap.emplace("__VA_ARGS__",count++);
}
+
// strip definition part
std::string definition;
std::string in=ds.substr(i_equals+1);
reg::Iterator re_it(in,reId);
+ reg::Iterator re_end;
size_t i=0;
// substitute all occurrences of formal arguments by their
// corresponding markers
- for (; re_it!=end; ++re_it)
+ for (; re_it!=re_end; ++re_it)
{
const auto &match = *re_it;
size_t pi = match.position();
@@ -3317,11 +3301,11 @@ static void initPredefined(yyscan_t yyscanner,const QCString &fileName)
def.nonRecursive = nonRecursive;
def.fileDef = state->yyFileDef;
def.fileName = fileName;
- def.varArgs = varArgs;
+ def.varArgs = hasVarArgs;
state->contextDefines.insert(std::make_pair(def.name.str(),def));
- //printf("#define '%s' '%s' #nargs=%d\n",
- // qPrint(def->name),qPrint(def->definition),def->nargs);
+ //printf("#define '%s' '%s' #nargs=%d hasVarArgs=%d\n",
+ // qPrint(def.name),qPrint(def.definition),def.nargs,def.varArgs);
}
}
else if (!ds.empty()) // predefined non-function macro definition
diff --git a/src/pycode.l b/src/pycode.l
index 6acf333..f24c8c9 100644
--- a/src/pycode.l
+++ b/src/pycode.l
@@ -183,7 +183,7 @@ LONGSTRINGCHAR [^\\"']
ESCAPESEQ ("\\")(.)
LONGSTRINGITEM ({LONGSTRINGCHAR}|{ESCAPESEQ})
SMALLQUOTE ("\"\""|"\""|"'"|"''")
-LONGSTRINGBLOCK ({LONGSTRINGITEM}+|{SMALLQUOTE})
+LONGSTRINGBLOCK ({LONGSTRINGITEM}|{SMALLQUOTE})
SHORTSTRING ("'"{SHORTSTRINGITEM}*"'"|'"'{SHORTSTRINGITEM}*'"')
SHORTSTRINGITEM ({SHORTSTRINGCHAR}|{ESCAPESEQ})
diff --git a/src/pyscanner.l b/src/pyscanner.l
index 4f331c9..a34dc18 100644
--- a/src/pyscanner.l
+++ b/src/pyscanner.l
@@ -180,7 +180,7 @@ LONGSTRINGCHAR [^\\"']
ESCAPESEQ ("\\")(.)
LONGSTRINGITEM ({LONGSTRINGCHAR}|{ESCAPESEQ})
SMALLQUOTE ("\"\""|"\""|"'"|"''")
-LONGSTRINGBLOCK ({LONGSTRINGITEM}+|{SMALLQUOTE})
+LONGSTRINGBLOCK ({LONGSTRINGITEM}|{SMALLQUOTE})
SHORTSTRING ("'"{SHORTSTRINGITEM}*"'"|'"'{SHORTSTRINGITEM}*'"')
SHORTSTRINGITEM ({SHORTSTRINGCHAR}|{ESCAPESEQ})
@@ -1838,18 +1838,26 @@ static void parseMain(yyscan_t yyscanner, const QCString &fileName,const char *f
yyextra->moduleScope+=baseName;
}
- yyextra->current = std::make_shared<Entry>();
- initEntry(yyscanner);
- yyextra->current->name = yyextra->moduleScope;
- yyextra->current->section = Entry::NAMESPACE_SEC;
- yyextra->current->type = "namespace";
- yyextra->current->fileName = yyextra->yyFileName;
- yyextra->current->startLine = yyextra->yyLineNr;
- yyextra->current->bodyLine = yyextra->yyLineNr;
-
- yyextra->current_root = yyextra->current;
-
- rt->moveToSubEntryAndRefresh(yyextra->current);
+ // add namespaces for each scope
+ QCString scope = yyextra->moduleScope;
+ int startPos = 0;
+ int pos;
+ do
+ {
+ pos = scope.find("::",startPos);
+ startPos=pos+2;
+ if (pos==-1) pos=(int)scope.length();
+ yyextra->current = std::make_shared<Entry>();
+ initEntry(yyscanner);
+ yyextra->current->name = scope.left(pos);
+ yyextra->current->section = Entry::NAMESPACE_SEC;
+ yyextra->current->type = "namespace";
+ yyextra->current->fileName = yyextra->yyFileName;
+ yyextra->current->startLine = yyextra->yyLineNr;
+ yyextra->current->bodyLine = yyextra->yyLineNr;
+ yyextra->current_root = yyextra->current;
+ rt->moveToSubEntryAndRefresh(yyextra->current);
+ } while (pos<(int)scope.length());
initParser(yyscanner);
diff --git a/src/qcstring.h b/src/qcstring.h
index ba5ac95..0b23071 100644
--- a/src/qcstring.h
+++ b/src/qcstring.h
@@ -398,6 +398,19 @@ class QCString
return m_rep.rfind(s.str(),0)==0; // looking "backward" starting and ending at index 0
}
+ bool endsWith(const char *s) const
+ {
+ if (m_rep.empty() || s==0) return s==0;
+ size_t l = strlen(s);
+ return m_rep.length()>=l && m_rep.compare(m_rep.length()-l, l, s, l)==0;
+ }
+
+ bool endsWith(const QCString &s) const
+ {
+ size_t l = s.length();
+ return m_rep.length()>=l && m_rep.compare(m_rep.length()-l, l, s.str())==0;
+ }
+
#define HAS_IMPLICIT_CAST_TO_PLAIN_C_STRING 0
#if HAS_IMPLICIT_CAST_TO_PLAIN_C_STRING
/** Converts the string to a plain C string */
diff --git a/src/resourcemgr.cpp b/src/resourcemgr.cpp
index 161e480..fb52d99 100644
--- a/src/resourcemgr.cpp
+++ b/src/resourcemgr.cpp
@@ -76,9 +76,11 @@ bool ResourceMgr::writeCategory(const QCString &categoryName,const QCString &tar
return TRUE;
}
-bool ResourceMgr::copyResourceAs(const QCString &name,const QCString &targetDir,const QCString &targetName) const
+bool ResourceMgr::copyResourceAs(const QCString &name,const QCString &targetDir,const QCString &targetName,bool append) const
{
std::string pathName = targetDir.str()+"/"+targetName.str();
+ std::ios_base::openmode mode = std::ofstream::out | std::ofstream::binary;
+ if (append) mode |= std::ofstream::app;
const Resource *res = get(name);
if (res)
{
@@ -86,7 +88,7 @@ bool ResourceMgr::copyResourceAs(const QCString &name,const QCString &targetDir,
{
case Resource::Verbatim:
{
- std::ofstream f(pathName,std::ofstream::out | std::ofstream::binary);
+ std::ofstream f(pathName,mode);
bool ok=false;
if (f.is_open())
{
@@ -137,7 +139,7 @@ bool ResourceMgr::copyResourceAs(const QCString &name,const QCString &targetDir,
break;
case Resource::CSS:
{
- std::ofstream t(pathName,std::ofstream::out | std::ofstream::binary);
+ std::ofstream t(pathName,mode);
if (t.is_open())
{
QCString buf(res->size+1);
@@ -157,7 +159,7 @@ bool ResourceMgr::copyResourceAs(const QCString &name,const QCString &targetDir,
break;
case Resource::SVG:
{
- std::ofstream t(pathName,std::ostream::out | std::ofstream::binary);
+ std::ofstream t(pathName,mode);
if (t.is_open())
{
QCString buf(res->size+1);
diff --git a/src/resourcemgr.h b/src/resourcemgr.h
index 7978e09..3c4c1b3 100644
--- a/src/resourcemgr.h
+++ b/src/resourcemgr.h
@@ -48,7 +48,7 @@ class ResourceMgr
bool copyResource(const QCString &name,const QCString &targetDir) const;
/** Copies a registered resource to a given target directory under a given target name */
- bool copyResourceAs(const QCString &name,const QCString &targetDir,const QCString &targetName) const;
+ bool copyResourceAs(const QCString &name,const QCString &targetDir,const QCString &targetName, bool append=false) const;
/** Gets the resource data as a C string */
QCString getAsString(const QCString &name) const;
diff --git a/src/scanner.l b/src/scanner.l
index f3d0bc3..1e781dc 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -1955,7 +1955,7 @@ NONLopt [^\n]*
//printf("Found %s\n",qPrint(yyextra->current->name));
BEGIN( ReadFuncArgType ) ;
}
- else if (yyextra->sharpCount<=0)
+ else
{
yyextra->current->name+="(";
yyextra->roundCount++;
@@ -4534,7 +4534,12 @@ NONLopt [^\n]*
unput(yyextra->lastCopyArgChar);
BEGIN( yyextra->lastCommentInArgContext );
}
-<CopyArgCommentLine>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
+<CopyArgCommentLine>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim type command (which could contain nested comments!)
+ yyextra->docBlockName="uml";
+ yyextra->fullArgString+=yytext;
+ BEGIN(CopyArgVerbatim);
+ }
+<CopyArgCommentLine>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"msc"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
yyextra->docBlockName=&yytext[1];
yyextra->fullArgString+=yytext;
BEGIN(CopyArgVerbatim);
@@ -4543,7 +4548,7 @@ NONLopt [^\n]*
yyextra->docBlockName=&yytext[1];
if (yyextra->docBlockName.at(1)=='[')
{
- yyextra->docBlockName.at(1)='}';
+ yyextra->docBlockName.at(1)=']';
}
if (yyextra->docBlockName.at(1)=='{')
{
@@ -4556,9 +4561,9 @@ NONLopt [^\n]*
yyextra->fullArgString+=yytext;
BEGIN(CopyArgVerbatim);
}
-<CopyArgVerbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endcode"|"f$"|"f]"|"f}"|"f)")/[^a-z_A-Z0-9\-] { // end of verbatim block
+<CopyArgVerbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"ebdmsc"|"enduml"|"endcode"|"f$"|"f]"|"f}"|"f)")/[^a-z_A-Z0-9\-] { // end of verbatim block
yyextra->fullArgString+=yytext;
- if (yytext[1]=='f') // end of formula
+ if (yytext[1]=='f' && yyextra->docBlockName==&yytext[1])
{
BEGIN(CopyArgCommentLine);
}
@@ -6556,10 +6561,18 @@ NONLopt [^\n]*
<DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
yyextra->docBlock << yytext;
yyextra->docBlockName=&yytext[1];
+ if (yyextra->docBlockName.at(1)=='[')
+ {
+ yyextra->docBlockName.at(1)=']';
+ }
if (yyextra->docBlockName.at(1)=='{')
{
yyextra->docBlockName.at(1)='}';
}
+ if (yyextra->docBlockName.at(1)=='(')
+ {
+ yyextra->docBlockName.at(1)=')';
+ }
yyextra->fencedSize=0;
yyextra->nestedComment=FALSE;
BEGIN(DocCopyBlock);
@@ -6571,7 +6584,14 @@ NONLopt [^\n]*
yyextra->nestedComment=FALSE;
BEGIN(DocCopyBlock);
}
-<DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
+<DocBlock>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
+ yyextra->docBlock << yytext;
+ yyextra->docBlockName="uml";
+ yyextra->fencedSize=0;
+ yyextra->nestedComment=FALSE;
+ BEGIN(DocCopyBlock);
+ }
+<DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"msc"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
yyextra->docBlock << yytext;
yyextra->docBlockName=&yytext[1];
yyextra->fencedSize=0;
@@ -6637,9 +6657,12 @@ NONLopt [^\n]*
}
<DocCopyBlock>[\\@]("f$"|"f]"|"f}"|"f)") {
yyextra->docBlock << yytext;
- BEGIN(DocBlock);
+ if (yyextra->docBlockName==&yytext[1])
+ {
+ BEGIN(DocBlock);
+ }
}
-<DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
+<DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"enduml"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
yyextra->docBlock << yytext;
if (&yytext[4]==yyextra->docBlockName)
{
diff --git a/src/searchindex.cpp b/src/searchindex.cpp
index cf09e67..f87cd33 100644
--- a/src/searchindex.cpp
+++ b/src/searchindex.cpp
@@ -1214,6 +1214,7 @@ void writeJavaScriptSearchIndex()
t << "</html>\n";
}
}
+
Doxygen::indexList->addStyleSheetFile("search/search.js");
}
diff --git a/src/template.cpp b/src/template.cpp
index 82b35f7..e1d9c79 100755
--- a/src/template.cpp
+++ b/src/template.cpp
@@ -98,30 +98,33 @@ static std::vector<QCString> split(const QCString &str,const QCString &sep,
/** Strips spaces surrounding `=` from string \a in, so
* `foo = 10 bar=5 baz= 'hello'` will become `foo=10 bar=5 baz='hello'`
*/
-static QCString removeSpacesAroundEquals(const QCString &s)
+static void removeSpacesAroundEquals(QCString &s)
{
- if (s.isEmpty()) return s;
- QCString result(s);
- const char *p=s.data();
- char *q = result.rawData();
- char c;
- while ((c=*p++))
+ //printf(">removeSpacesAroundEquals(%s)\n",qPrint(s));
+ uint i=0, dstIdx=0, l=s.length();
+ while (i<l)
{
- if (c==' ') // found a space, see if there is a = as well
+ char c = s[i++];
+ if (c==' ')
{
- const char *t = p;
- bool found=FALSE;
- while (*t==' ' || *t=='=') { if (*t++=='=') found=TRUE; }
- if (found)
+ bool found=false;
+ // look ahead for space or '='
+ uint j=i;
+ while (j<l && (s[j]==' '|| s[j]=='='))
+ {
+ if (s[j]=='=') found=true;
+ j++;
+ }
+ if (found) // found a '=', write it without spaces
{
- c='=';
- p=t; // move p to end of '\s*=\s*' sequence
+ c = '=';
+ i=j;
}
}
- *q++=c;
+ s[dstIdx++]=c;
}
- if (q<p) result.resize(static_cast<uint>(q-result.data())+1);
- return result;
+ s.resize(dstIdx+1);
+ //printf("<removeSpacesAroundEquals(%s)\n",qPrint(s));
}
//----------------------------------------------------------------------------
@@ -130,9 +133,9 @@ static QCString removeSpacesAroundEquals(const QCString &s)
static QCString replace(const QCString &s,char csrc,char cdst)
{
QCString result = s;
- for (char *p=result.data();*p;p++)
+ for (uint i=0;i<result.length();i++)
{
- if (*p==csrc) *p=cdst;
+ if (result[i]==csrc) result[i]=cdst;
}
return result;
}
@@ -288,6 +291,17 @@ TemplateVariant TemplateStruct::get(const QCString &name) const
return it!=p->fields.end() ? it->second : TemplateVariant();
}
+StringVector TemplateStruct::fields() const
+{
+ StringVector result;
+ for (const auto &kv : p->fields)
+ {
+ result.push_back(kv.first);
+ }
+ std::sort(result.begin(),result.end());
+ return result;
+}
+
TemplateStruct *TemplateStruct::alloc()
{
return new TemplateStruct;
@@ -514,6 +528,7 @@ class TemplateContextImpl : public TemplateContext
void push();
void pop();
void set(const QCString &name,const TemplateVariant &v);
+ void update(const QCString &name,const TemplateVariant &v);
TemplateVariant get(const QCString &name) const;
const TemplateVariant *getRef(const QCString &name) const;
void setOutputDirectory(const QCString &dir)
@@ -1078,14 +1093,14 @@ class FilterAlphaIndex
private:
struct ListElem
{
- ListElem(uint k,const TemplateVariant &v) : key(k), value(v) {}
- QCString key;
+ ListElem(std::string k,const TemplateVariant &v) : key(k), value(v) {}
+ std::string key;
TemplateVariant value;
};
- static QCString keyToLabel(const QCString &startLetter)
+ static QCString keyToLabel(const char *startLetter)
{
- if (startLetter.isEmpty()) return startLetter;
- const char *p = startLetter.data();
+ //printf(">keyToLabel(%s)\n",qPrint(startLetter));
+ const char *p = startLetter;
char c = *p;
QCString result;
if (c<127 && c>31) // printable ASCII character
@@ -1102,16 +1117,14 @@ class FilterAlphaIndex
result+=hex[((unsigned char)c)&0xf];
}
}
+ //printf("<keyToLabel(%s)\n",qPrint(result));
return result;
}
- static uint determineSortKey(TemplateStructIntf *s,const QCString &attribName)
+ static std::string determineSortKey(TemplateStructIntf *s,const QCString &attribName)
{
TemplateVariant v = s->get(attribName);
int index = getPrefixIndex(v.toString());
- return getUnicodeForUTF8CharAt(
- convertUTF8ToUpper(
- getUTF8CharAt(v.toString().str(),index)
- ),0);
+ return convertUTF8ToUpper(getUTF8CharAt(v.toString().str(),index));
}
public:
@@ -1134,7 +1147,7 @@ class FilterAlphaIndex
TemplateStructIntf *s = item.toStruct();
if (s)
{
- uint sortKey = determineSortKey(s,args.toString());
+ std::string sortKey = determineSortKey(s,args.toString());
sortList.emplace_back(sortKey,item);
//printf("sortKey=%s\n",qPrint(sortKey));
}
@@ -1147,7 +1160,7 @@ class FilterAlphaIndex
[](const auto &lhs,const auto &rhs) { return lhs.key < rhs.key; });
// create an index from the sorted list
- QCString letter;
+ std::string letter;
TemplateStruct *indexNode = 0;
TemplateList *indexList = 0;
for (const auto &elem : sortList)
@@ -1158,7 +1171,7 @@ class FilterAlphaIndex
indexNode = TemplateStruct::alloc();
indexList = TemplateList::alloc();
indexNode->set("letter", elem.key);
- indexNode->set("label", keyToLabel(elem.key));
+ indexNode->set("label", keyToLabel(elem.key.c_str()));
indexNode->set("items",indexList);
result->append(indexNode);
letter=elem.key;
@@ -1282,6 +1295,72 @@ class FilterIsAbsoluteURL
//--------------------------------------------------------------------
+/** @brief The implementation of the "lower" filter */
+class FilterLower
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
+ {
+ if (v.isValid() && v.type()==TemplateVariant::String)
+ {
+ return v.toString().lower();
+ }
+ return v;
+ }
+};
+
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "upper" filter */
+class FilterUpper
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
+ {
+ if (v.isValid() && v.type()==TemplateVariant::String)
+ {
+ return v.toString().upper();
+ }
+ return v;
+ }
+};
+
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "upper" filter */
+class FilterHex
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
+ {
+ if (v.isValid())
+ {
+ return QCString().sprintf("%x",v.toInt());
+ }
+ return v;
+ }
+};
+
+
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "e" filter */
+class FilterEscape
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
+ {
+ if (v.isValid() && v.type()==TemplateVariant::String)
+ {
+ return convertToHtml(v.toString());
+ }
+ return v;
+ }
+};
+
+
+//--------------------------------------------------------------------
+
/** @brief The implementation of the "decodeURL" filter
* The leading character is removed from the value in case it is a ^ or !.
* - ^ is used to encode a absolute URL
@@ -1357,9 +1436,13 @@ class TemplateFilterFactory
// register a handlers for each filter we support
static TemplateFilterFactory::AutoRegister<FilterAdd> fAdd("add");
static TemplateFilterFactory::AutoRegister<FilterGet> fGet("get");
+static TemplateFilterFactory::AutoRegister<FilterHex> fHex("hex");
static TemplateFilterFactory::AutoRegister<FilterRaw> fRaw("raw");
static TemplateFilterFactory::AutoRegister<FilterList> fList("list");
+static TemplateFilterFactory::AutoRegister<FilterLower> fLower("lower");
+static TemplateFilterFactory::AutoRegister<FilterUpper> fUpper("upper");
static TemplateFilterFactory::AutoRegister<FilterAppend> fAppend("append");
+static TemplateFilterFactory::AutoRegister<FilterEscape> fEscape("escape");
static TemplateFilterFactory::AutoRegister<FilterLength> fLength("length");
static TemplateFilterFactory::AutoRegister<FilterNoWrap> fNoWrap("nowrap");
static TemplateFilterFactory::AutoRegister<FilterFlatten> fFlatten("flatten");
@@ -1409,7 +1492,7 @@ class ExprAstVariable : public ExprAst
{
public:
ExprAstVariable(const QCString &name) : m_name(name)
- { TRACE(("ExprAstVariable(%s)\n",name)); }
+ { TRACE(("ExprAstVariable(%s)\n",name.data())); }
const QCString &name() const { return m_name; }
virtual TemplateVariant resolve(TemplateContext *c)
{
@@ -1461,7 +1544,7 @@ class ExprAstFilter : public ExprAst
{
public:
ExprAstFilter(const QCString &name,ExprAst *arg) : m_name(name), m_arg(arg)
- { TRACE(("ExprAstFilter(%s)\n",name)); }
+ { TRACE(("ExprAstFilter(%s)\n",name.data())); }
~ExprAstFilter() { delete m_arg; }
const QCString &name() const { return m_name; }
TemplateVariant apply(const TemplateVariant &v,TemplateContext *c)
@@ -1506,7 +1589,7 @@ class ExprAstLiteral : public ExprAst
{
public:
ExprAstLiteral(const QCString &lit) : m_literal(lit)
- { TRACE(("ExprAstLiteral(%s)\n",lit)); }
+ { TRACE(("ExprAstLiteral(%s)\n",lit.data())); }
const QCString &literal() const { return m_literal; }
virtual TemplateVariant resolve(TemplateContext *) { return TemplateVariant(m_literal); }
private:
@@ -1969,6 +2052,7 @@ class ExpressionParser
{
warn(m_parser->templateName(),m_line,"unexpected operator '%s' in expression",
Operator::toString(m_curToken.op));
+ abort();
}
break;
default:
@@ -2261,8 +2345,8 @@ class ExpressionParser
m_curToken.id = s;
p++;
}
- //TRACE(("token type=%d op=%d num=%d id=%s\n",
- // m_curToken.type,m_curToken.op,m_curToken.num,qPrint(m_curToken.id)));
+ TRACE(("token type=%d op=%d num=%d id=%s\n",
+ m_curToken.type,m_curToken.op,m_curToken.num,qPrint(m_curToken.id)));
m_tokenStream = p;
return TRUE;
@@ -2305,6 +2389,7 @@ class TemplateStructWeakRef : public TemplateStructIntf
public:
TemplateStructWeakRef(TemplateStructIntf *ref) : m_ref(ref), m_refCount(0) {}
virtual TemplateVariant get(const QCString &name) const { return m_ref->get(name); }
+ virtual StringVector fields() const { return m_ref->fields(); }
virtual int addRef() { return ++m_refCount; }
virtual int release() { int count=--m_refCount; if (count<=0) { delete this; } return count; }
private:
@@ -2382,6 +2467,23 @@ void TemplateContextImpl::set(const QCString &name,const TemplateVariant &v)
ctx.insert(std::make_pair(name.str(),v));
}
+void TemplateContextImpl::update(const QCString &name,const TemplateVariant &v)
+{
+ int depth=0;
+ for (auto &ctx : m_contextStack)
+ {
+ auto it = ctx.find(name.str());
+ if (it!=ctx.end())
+ {
+ ctx.erase(it);
+ ctx.insert(std::make_pair(name.str(),v));
+ return;
+ }
+ depth++;
+ }
+ warn(m_templateName,m_line,"requesting update for non-existing variable '%s'",qPrint(name));
+}
+
TemplateVariant TemplateContextImpl::get(const QCString &name) const
{
int i=name.find('.');
@@ -3544,21 +3646,16 @@ class TemplateNodeInclude : public TemplateNodeCreator<TemplateNodeInclude>
static void stripLeadingWhiteSpace(QCString &s)
{
- const char *src = s.data();
- if (src)
+ uint i=0, dstIdx=0, l=s.length();
+ bool skipSpaces=true;
+ while (i<l)
{
- char *dst = s.rawData();
- char c;
- bool skipSpaces=TRUE;
- while ((c=*src++))
- {
- if (c=='\n') { *dst++=c; skipSpaces=TRUE; }
- else if (c==' ' && skipSpaces) {}
- else { *dst++=c; skipSpaces=FALSE; }
- }
- *dst='\0';
- s.resize( (int)(dst - src) + 1 );
+ char c = s[i++];
+ if (c=='\n') { s[dstIdx++]=c; skipSpaces=true; }
+ else if (c==' ' && skipSpaces) {}
+ else { s[dstIdx++] = c; skipSpaces=false; }
}
+ s.resize(dstIdx+1);
}
/** @brief Class representing an 'create' tag in a template */
@@ -3945,7 +4042,8 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith>
{
TRACE(("{TemplateNodeWith(%s)\n",qPrint(data)));
ExpressionParser expParser(parser,line);
- QCString filteredData = removeSpacesAroundEquals(data);
+ QCString filteredData = data;
+ removeSpacesAroundEquals(filteredData);
std::vector<QCString> args = split(filteredData," ");
auto it = args.begin();
while (it!=args.end())
@@ -4114,6 +4212,52 @@ class TemplateNodeSet : public TemplateNodeCreator<TemplateNodeSet>
//----------------------------------------------------------
+/** @brief Class representing an 'update' tag in a template */
+class TemplateNodeUpdate : public TemplateNodeCreator<TemplateNodeUpdate>
+{
+ struct Mapping
+ {
+ Mapping(const QCString &n,ExprAst *e) : name(n), value(e) {}
+ ~Mapping() { }
+ QCString name;
+ ExprAst *value = 0;
+ };
+ public:
+ TemplateNodeUpdate(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeUpdate>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeUpdate(%s)\n",qPrint(data)));
+ ExpressionParser expParser(parser,line);
+ // data format: name=expression
+ int j=data.find('=');
+ ExprAst *expr = 0;
+ if (j>0 && (expr = expParser.parse(data.mid(j+1))))
+ {
+ m_mapping = std::make_unique<Mapping>(data.left(j),expr);
+ }
+ TRACE(("}TemplateNodeUpdate(%s)\n",qPrint(data)));
+ }
+ ~TemplateNodeUpdate()
+ {
+ }
+ void render(TextStream &, TemplateContext *c)
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ if (ci==0) return; // should not happen
+ ci->setLocation(m_templateName,m_line);
+ if (m_mapping)
+ {
+ TemplateVariant value = m_mapping->value->resolve(c);
+ ci->update(m_mapping->name,value);
+ }
+ }
+ private:
+ std::unique_ptr<Mapping> m_mapping;
+};
+
+
+//----------------------------------------------------------
+
/** @brief Class representing an 'spaceless' tag in a template */
class TemplateNodeSpaceless : public TemplateNodeCreator<TemplateNodeSpaceless>
{
@@ -4313,6 +4457,12 @@ class TemplateNodeResource : public TemplateNodeCreator<TemplateNodeResource>
m_resExpr = ep.parse(data.left(i)); // part before as
m_asExpr = ep.parse(data.mid(i+4)); // part after as
}
+ else if ((i=data.find(" append "))!=-1) // resource a appends to b
+ {
+ m_resExpr = ep.parse(data.left(i)); // part before append
+ m_asExpr = ep.parse(data.mid(i+8)); // part after append
+ m_append = true;
+ }
else // resource a
{
m_resExpr = ep.parse(data);
@@ -4345,11 +4495,12 @@ class TemplateNodeResource : public TemplateNodeCreator<TemplateNodeResource>
QCString targetFile = m_asExpr->resolve(c).toString();
mkpath(ci,targetFile.str());
if (targetFile.isEmpty())
- { ci->warn(m_templateName,m_line,"invalid parameter at right side of 'as' for resource command\n");
+ {
+ ci->warn(m_templateName,m_line,"invalid parameter at right side of '%s' for resource command\n", m_append ? "append" : "as");
}
else
{
- ResourceMgr::instance().copyResourceAs(resourceFile,outputDirectory,targetFile);
+ ResourceMgr::instance().copyResourceAs(resourceFile,outputDirectory,targetFile,m_append);
}
}
else
@@ -4362,6 +4513,7 @@ class TemplateNodeResource : public TemplateNodeCreator<TemplateNodeResource>
private:
ExprAst *m_resExpr = 0;
ExprAst *m_asExpr = 0;
+ bool m_append = false;
};
//----------------------------------------------------------
@@ -4477,6 +4629,7 @@ static TemplateNodeFactory::AutoRegister<TemplateNodeRange> autoRefRange
static TemplateNodeFactory::AutoRegister<TemplateNodeExtend> autoRefExtend("extend");
static TemplateNodeFactory::AutoRegister<TemplateNodeCreate> autoRefCreate("create");
static TemplateNodeFactory::AutoRegister<TemplateNodeRepeat> autoRefRepeat("repeat");
+static TemplateNodeFactory::AutoRegister<TemplateNodeUpdate> autoRefUpdate("update");
static TemplateNodeFactory::AutoRegister<TemplateNodeInclude> autoRefInclude("include");
static TemplateNodeFactory::AutoRegister<TemplateNodeMarkers> autoRefMarkers("markers");
static TemplateNodeFactory::AutoRegister<TemplateNodeTabbing> autoRefTabbing("tabbing");
@@ -4797,7 +4950,7 @@ void TemplateLexer::addToken(TemplateTokenStream &tokens,
{
if (startPos<endPos)
{
- int len = endPos-startPos+1;
+ int len = endPos-startPos;
QCString text = data.mid(startPos,len);
if (type!=TemplateToken::Text) text = text.stripWhiteSpace();
tokens.push_back(std::make_unique<TemplateToken>(type,text,line));
@@ -4822,8 +4975,8 @@ void TemplateParser::parse(
while (hasNextToken())
{
auto tok = takeNextToken();
- //printf("%p:Token type=%d data='%s' line=%d\n",
- // parent,tok->type,qPrint(tok->data),tok->line);
+ TRACE(("%p:Token type=%d data='%s' line=%d\n",
+ (void*)parent,tok->type,qPrint(tok->data),tok->line));
switch(tok->type)
{
case TemplateToken::Text:
@@ -5178,4 +5331,50 @@ void TemplateEngine::setTemplateDir(const QCString &dirName)
p->setTemplateDir(dirName);
}
+//-----------------------------------------------------------------------------------------
+
+QCString TemplateVariant::listToString() const
+{
+ QCString result="[";
+ TemplateListIntf *list = toList();
+ if (list)
+ {
+ bool first=true;
+ TemplateVariant ve;
+ TemplateListIntf::ConstIterator *it = list->createIterator();
+ for (it->toFirst();it->current(ve);it->toNext())
+ {
+ if (!first) result+=",\n";
+ result+="'"+ve.toString()+"'";
+ first=false;
+ }
+ delete it;
+ }
+ result+="]";
+ return result;
+}
+
+QCString TemplateVariant::structToString() const
+{
+ QCString result="{";
+ TemplateStructIntf *strukt = toStruct();
+ if (strukt)
+ {
+ bool first=true;
+ for (const auto &s : strukt->fields())
+ {
+ if (!first) result+=",";
+ result+=s;
+ if (dynamic_cast<TemplateStructWeakRef*>(strukt)==0) // avoid endless recursion
+ {
+ result+=":'";
+ result+=strukt->get(QCString(s)).toString();
+ result+="'";
+ }
+ first=false;
+ }
+ }
+ result+="}";
+ return result;
+}
diff --git a/src/template.h b/src/template.h
index dee063d..7d803a3 100644
--- a/src/template.h
+++ b/src/template.h
@@ -19,6 +19,7 @@
#include <vector>
#include "qcstring.h"
+#include "containers.h"
class TemplateListIntf;
class TemplateStructIntf;
@@ -28,7 +29,7 @@ class TextStream;
/** @defgroup template_api Template API
*
* This is the API for a
- * <a href="https://docs.djangoproject.com/en/1.6/topics/templates/">Django</a>
+ * <a href="https://www.djangoproject.com/">Django</a>
* compatible template system written in C++.
* It is somewhat inspired by Stephen Kelly's
* <a href="http://www.gitorious.org/grantlee/pages/Home">Grantlee</a>.
@@ -175,6 +176,9 @@ class TemplateVariant
/** Constructs a new variant with a string value \a s. */
TemplateVariant(const QCString &s,bool raw=FALSE) : m_type(String), m_strVal(s), m_strukt(0), m_raw(raw) {}
+ /** Constructs a new variant with a string value \a s. */
+ TemplateVariant(const std::string &s,bool raw=FALSE) : m_type(String), m_strVal(s), m_strukt(0), m_raw(raw) {}
+
/** Constructs a new variant with a struct value \a s.
* @note. The variant will hold a reference to the object.
*/
@@ -228,6 +232,9 @@ class TemplateVariant
}
}
+ QCString listToString() const;
+ QCString structToString() const;
+
/** Returns the variant as a string. */
QCString toString() const
{
@@ -237,8 +244,8 @@ class TemplateVariant
case Bool: return m_boolVal ? "true" : "false";
case Integer: return QCString().setNum(m_intVal);
case String: return m_strVal;
- case Struct: return "[struct]";
- case List: return "[list]";
+ case Struct: return structToString();
+ case List: return listToString();
case Function: return "[function]";
}
return QCString();
@@ -414,6 +421,9 @@ class TemplateStructIntf
*/
virtual TemplateVariant get(const QCString &name) const = 0;
+ /** Return the list of fields. */
+ virtual StringVector fields() const = 0;
+
/** Increase object's reference count */
virtual int addRef() = 0;
@@ -428,6 +438,7 @@ class TemplateStruct : public TemplateStructIntf
public:
// TemplateStructIntf methods
virtual TemplateVariant get(const QCString &name) const;
+ virtual StringVector fields() const;
virtual int addRef();
virtual int release();