summaryrefslogtreecommitdiff
path: root/src/template.cpp
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2021-10-15 11:16:22 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2021-10-15 11:16:22 +0900
commit558fa54c62ec59357cb5c40a411f16f1c1754f33 (patch)
tree9468f1b169143cbb375fc223ca2f78539a908085 /src/template.cpp
parentce6f802772f02771c3bf86ccf78d0fc1731947c5 (diff)
downloaddoxygen-558fa54c62ec59357cb5c40a411f16f1c1754f33.tar.gz
doxygen-558fa54c62ec59357cb5c40a411f16f1c1754f33.tar.bz2
doxygen-558fa54c62ec59357cb5c40a411f16f1c1754f33.zip
Imported Upstream version 1.9.2upstream/1.9.2
Diffstat (limited to 'src/template.cpp')
-rwxr-xr-x[-rw-r--r--]src/template.cpp1660
1 files changed, 899 insertions, 761 deletions
diff --git a/src/template.cpp b/src/template.cpp
index d5e8275..aeab71c 100644..100755
--- a/src/template.cpp
+++ b/src/template.cpp
@@ -15,26 +15,22 @@
#include "template.h"
-#include <stdio.h>
-#include <stdarg.h>
-
-#include <qlist.h>
-#include <qarray.h>
-#include <qdict.h>
-#include <qstrlist.h>
-#include <qvaluelist.h>
-#include <qstack.h>
-#include <qfile.h>
-#include <qregexp.h>
-#include <qcstring.h>
-#include <qdir.h>
-
-#include "sortdict.h"
-#include "ftextstream.h"
+#include <vector>
+#include <algorithm>
+#include <unordered_map>
+#include <deque>
+#include <cstdio>
+#include <fstream>
+#include <sstream>
+
#include "message.h"
#include "util.h"
#include "resourcemgr.h"
#include "portable.h"
+#include "regex.h"
+#include "fileinfo.h"
+#include "dir.h"
+#include "utf8.h"
#define ENABLE_TRACING 0
@@ -102,40 +98,44 @@ 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 char *s)
+static void removeSpacesAroundEquals(QCString &s)
{
- QCString result(s);
- const char *p=result.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]=='='))
{
- c='=';
- p=t; // move p to end of '\s*=\s*' sequence
+ if (s[j]=='=') found=true;
+ j++;
+ }
+ if (found) // found a '=', write it without spaces
+ {
+ c = '=';
+ i=j;
}
}
- *q++=c;
+ s[dstIdx++]=c;
}
- if (q<p) result.resize(q-result.data()+1);
- return result;
+ s.resize(dstIdx+1);
+ //printf("<removeSpacesAroundEquals(%s)\n",qPrint(s));
}
//----------------------------------------------------------------------------
#if ENABLE_TRACING
-static QCString replace(const char *s,char csrc,char cdst)
+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;
}
@@ -145,96 +145,121 @@ static QCString replace(const char *s,char csrc,char cdst)
TemplateVariant::TemplateVariant(TemplateStructIntf *s)
- : m_type(Struct), m_strukt(s), m_raw(FALSE)
{
- m_strukt->addRef();
+ m_variant.set<TemplateStructIntf*>(s);
+ s->addRef();
}
TemplateVariant::TemplateVariant(TemplateListIntf *l)
- : m_type(List), m_list(l), m_raw(FALSE)
{
- m_list->addRef();
+ m_variant.set<TemplateListIntf*>(l);
+ l->addRef();
}
TemplateVariant::~TemplateVariant()
{
- if (m_type==Struct) m_strukt->release();
- else if (m_type==List) m_list->release();
+ try
+ {
+ if (m_variant.is<TemplateStructIntf*>()) m_variant.get<TemplateStructIntf*>()->release();
+ else if (m_variant.is<TemplateListIntf*>()) m_variant.get<TemplateListIntf*>()->release();
+ }
+ catch(...)
+ {
+ // should never happen
+ }
}
TemplateVariant::TemplateVariant(const TemplateVariant &v)
- : m_type(v.m_type), m_strukt(0), m_raw(FALSE)
{
- m_raw = v.m_raw;
- switch (m_type)
- {
- case None: break;
- case Bool: m_boolVal = v.m_boolVal; break;
- case Integer: m_intVal = v.m_intVal; break;
- case String: m_strVal = v.m_strVal; break;
- case Struct: m_strukt = v.m_strukt; m_strukt->addRef(); break;
- case List: m_list = v.m_list; m_list->addRef(); break;
- case Function: m_delegate= v.m_delegate;break;
- }
+ m_raw = v.m_raw;
+ m_variant = v.m_variant;
+ if (m_variant.is<TemplateStructIntf*>()) m_variant.get<TemplateStructIntf*>()->addRef();
+ else if (m_variant.is<TemplateListIntf*>()) m_variant.get<TemplateListIntf*>()->addRef();
}
-TemplateVariant &TemplateVariant::operator=(const TemplateVariant &v)
+TemplateVariant::TemplateVariant(TemplateVariant &&v)
{
- // assignment can change the type of the variable, so we have to be
- // careful with reference counted content.
- TemplateStructIntf *tmpStruct = m_type==Struct ? m_strukt : 0;
- TemplateListIntf *tmpList = m_type==List ? m_list : 0;
- Type tmpType = m_type;
+ m_raw = std::move(v.m_raw);
+ m_variant = std::move(v.m_variant);
+ v.m_variant.invalidate();
+}
- m_type = v.m_type;
- m_raw = v.m_raw;
- switch (m_type)
+TemplateVariant &TemplateVariant::operator=(const TemplateVariant &v)
+{
+ if (this!=&v)
{
- case None: break;
- case Bool: m_boolVal = v.m_boolVal; break;
- case Integer: m_intVal = v.m_intVal; break;
- case String: m_strVal = v.m_strVal; break;
- case Struct: m_strukt = v.m_strukt; m_strukt->addRef(); break;
- case List: m_list = v.m_list; m_list->addRef(); break;
- case Function: m_delegate= v.m_delegate;break;
+ // assignment can change the type of the variable, so we have to be
+ // careful with reference counted content.
+ TemplateStructIntf *tmpStruct = m_variant.is<TemplateStructIntf*>() ? m_variant.get<TemplateStructIntf*>() : nullptr;
+ TemplateListIntf *tmpList = m_variant.is<TemplateListIntf*>() ? m_variant.get<TemplateListIntf*>() : nullptr;
+
+ m_raw = v.m_raw;
+ m_variant = v.m_variant;
+
+ if (m_variant.is<TemplateStructIntf*>()) m_variant.get<TemplateStructIntf*>()->addRef();
+ else if (m_variant.is<TemplateListIntf*>()) m_variant.get<TemplateListIntf*>()->addRef();
+
+ // release overwritten reference counted values
+ if (tmpStruct) tmpStruct->release();
+ else if (tmpList ) tmpList->release();
}
+ return *this;
+}
- // release overwritten reference counted values
- if (tmpType==Struct && tmpStruct) tmpStruct->release();
- else if (tmpType==List && tmpList ) tmpList->release();
+TemplateVariant &TemplateVariant::operator=(TemplateVariant &&v)
+{
+ m_raw = std::move(v.m_raw);
+ m_variant = std::move(v.m_variant);
+ v.m_variant.invalidate();
return *this;
}
bool TemplateVariant::toBool() const
{
- switch (m_type)
+ switch (type())
{
- case None: return FALSE;
- case Bool: return m_boolVal;
- case Integer: return m_intVal!=0;
- case String: return !m_strVal.isEmpty();
- case Struct: return TRUE;
- case List: return m_list->count()!=0;
- case Function: return FALSE;
+ case Type::None: return false;
+ case Type::Bool: return m_variant.get<bool>();
+ case Type::Int: return m_variant.get<int>()!=0;
+ case Type::String: return !m_variant.get<QCString>().isEmpty();
+ case Type::Struct: return true;
+ case Type::List: return m_variant.get<TemplateListIntf*>()->count()!=0;
+ case Type::Function: return false;
}
return FALSE;
}
int TemplateVariant::toInt() const
{
- switch (m_type)
+ switch (type())
{
- case None: return 0;
- case Bool: return m_boolVal ? 1 : 0;
- case Integer: return m_intVal;
- case String: return m_strVal.toInt();
- case Struct: return 0;
- case List: return m_list->count();
- case Function: return 0;
+ case Type::None: return 0;
+ case Type::Bool: return m_variant.get<bool>() ? 1 : 0;
+ case Type::Int: return m_variant.get<int>();
+ case Type::String: return !m_variant.get<QCString>().toInt();
+ case Type::Struct: return 0;
+ case Type::List: return m_variant.get<TemplateListIntf*>()->count();
+ case Type::Function: return 0;
}
return 0;
}
+QCString TemplateVariant::toString() const
+{
+ switch (type())
+ {
+ case Type::None: return QCString();
+ case Type::Bool: return m_variant.get<bool>() ? "true" : "false";
+ case Type::Int: return QCString().setNum(m_variant.get<int>());
+ case Type::String: return m_variant.get<QCString>();
+ case Type::Struct: return structToString();
+ case Type::List: return listToString();
+ case Type::Function: return "[function]";
+ }
+ return QCString();
+}
+
+
//- Template struct implementation --------------------------------------------
@@ -242,9 +267,8 @@ int TemplateVariant::toInt() const
class TemplateStruct::Private
{
public:
- Private() : fields(17), refCount(0)
- { fields.setAutoDelete(TRUE); }
- QDict<TemplateVariant> fields;
+ Private() : refCount(0) {}
+ std::unordered_map<std::string,TemplateVariant> fields;
int refCount = 0;
};
@@ -273,23 +297,34 @@ int TemplateStruct::release()
return count;
}
-void TemplateStruct::set(const char *name,const TemplateVariant &v)
+void TemplateStruct::set(const QCString &name,const TemplateVariant &v)
{
- TemplateVariant *pv = p->fields.find(name);
- if (pv) // change existing field
+ auto it = p->fields.find(name.str());
+ if (it!=p->fields.end()) // change existing field
{
- *pv = v;
+ it->second = v;
}
else // insert new field
{
- p->fields.insert(name,new TemplateVariant(v));
+ p->fields.insert(std::make_pair(name.str(),v));
}
}
-TemplateVariant TemplateStruct::get(const char *name) const
+TemplateVariant TemplateStruct::get(const QCString &name) const
{
- TemplateVariant *v = p->fields.find(name);
- return v ? *v : TemplateVariant();
+ auto it = p->fields.find(name.str());
+ 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()
@@ -487,13 +522,14 @@ class TemplateBlockContext
public:
TemplateBlockContext();
TemplateNodeBlock *get(const QCString &name) const;
- TemplateNodeBlock *pop(const QCString &name) const;
+ TemplateNodeBlock *pop(const QCString &name);
void add(TemplateNodeBlock *block);
void add(TemplateBlockContext *ctx);
void push(TemplateNodeBlock *block);
void clear();
+ using NodeBlockList = std::deque<TemplateNodeBlock*>;
private:
- QDict< QList<TemplateNodeBlock> > m_blocks;
+ std::map< std::string, NodeBlockList > m_blocks;
};
/** @brief A container to store a key-value pair */
@@ -516,7 +552,8 @@ class TemplateContextImpl : public TemplateContext
// TemplateContext methods
void push();
void pop();
- void set(const char *name,const TemplateVariant &v);
+ 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)
@@ -524,11 +561,12 @@ class TemplateContextImpl : public TemplateContext
void setEscapeIntf(const QCString &ext,TemplateEscapeIntf *intf)
{
int i=(!ext.isEmpty() && ext.at(0)=='.') ? 1 : 0;
- m_escapeIntfDict.insert(ext.mid(i),new TemplateEscapeIntf*(intf));
+ m_escapeIntfMap.insert(std::make_pair(ext.mid(i).str(),intf));
}
void selectEscapeIntf(const QCString &ext)
- { TemplateEscapeIntf **ppIntf = m_escapeIntfDict.find(ext);
- m_activeEscapeIntf = ppIntf ? *ppIntf : 0;
+ {
+ auto it = m_escapeIntfMap.find(ext.str());
+ m_activeEscapeIntf = it!=m_escapeIntfMap.end() ? it->second : 0;
}
void setActiveEscapeIntf(TemplateEscapeIntf *intf) { m_activeEscapeIntf = intf; }
void setSpacelessIntf(TemplateSpacelessIntf *intf) { m_spacelessIntf = intf; }
@@ -555,7 +593,7 @@ class TemplateContextImpl : public TemplateContext
QCString encoding() const { return m_encoding; }
void setEncoding(const QCString &file,int line,const QCString &enc);
QCString recode(const QCString &s);
- void warn(const char *fileName,int line,const char *fmt,...) const;
+ void warn(const QCString &fileName,int line,const char *fmt,...) const;
// index related functions
void openSubIndex(const QCString &indexName);
@@ -567,15 +605,15 @@ class TemplateContextImpl : public TemplateContext
QCString m_templateName;
int m_line = 0;
QCString m_outputDir;
- QList< QDict<TemplateVariant> > m_contextStack;
+ std::deque< std::map<std::string,TemplateVariant> > m_contextStack;
TemplateBlockContext m_blockContext;
- QDict<TemplateEscapeIntf*> m_escapeIntfDict;
+ std::unordered_map<std::string, TemplateEscapeIntf*> m_escapeIntfMap;
TemplateEscapeIntf *m_activeEscapeIntf = 0;
TemplateSpacelessIntf *m_spacelessIntf = 0;
bool m_spacelessEnabled = false;
bool m_tabbingEnabled = false;
TemplateAutoRef<TemplateStruct> m_indices;
- QDict< QStack<TemplateVariant> > m_indexStacks;
+ std::unordered_map< std::string, std::stack<TemplateVariant> > m_indexStacks;
QCString m_encoding;
void *m_fromUtf8 = 0;
};
@@ -588,12 +626,11 @@ class FilterAdd
public:
static int variantIntValue(const TemplateVariant &v,bool &isInt)
{
- isInt = v.type()==TemplateVariant::Integer;
- if (!isInt && v.type()==TemplateVariant::String)
+ if (!v.isInt() && v.isString())
{
return v.toString().toInt(&isInt);
}
- return isInt ? v.toInt() : 0;
+ return v.isInt() ? v.toInt() : 0;
}
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &arg)
{
@@ -609,7 +646,7 @@ class FilterAdd
{
return lhsValue+rhsValue;
}
- else if (v.type()==TemplateVariant::String && arg.type()==TemplateVariant::String)
+ else if (v.isString() && arg.isString())
{
return TemplateVariant(v.toString() + arg.toString());
}
@@ -628,15 +665,15 @@ class FilterGet
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &arg)
{
- if (v.isValid() && v.type()==TemplateVariant::Struct && arg.type()==TemplateVariant::String)
+ if (v.isValid() && v.isStruct() && arg.isString())
{
TemplateVariant result = v.toStruct()->get(arg.toString());
- //printf("\nok[%s]=%d\n",arg.toString().data(),result.type());
+ //printf("\nok[%s]=%d\n",qPrint(arg.toString()),result.type());
return result;
}
else
{
- //printf("\nnok[%s]\n",arg.toString().data());
+ //printf("\nnok[%s]\n",qPrint(arg.toString()));
return FALSE;
}
}
@@ -650,7 +687,7 @@ class FilterRaw
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
{
- if (v.isValid() && (v.type()==TemplateVariant::String || v.type()==TemplateVariant::Integer))
+ if (v.isValid() && (v.isString() || v.isInt()))
{
return TemplateVariant(v.toString(),TRUE);
}
@@ -663,6 +700,46 @@ class FilterRaw
//-----------------------------------------------------------------------------
+/** @brief The implementation of the "keep" filter */
+class FilterKeep
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &args)
+ {
+ if (v.isValid() && v.isList() && args.isString())
+ {
+ //printf("FilterKeep::apply: v=%s args=%s\n",qPrint(v.toString()),qPrint(args.toString()));
+ TemplateListIntf::ConstIterator *it = v.toList()->createIterator();
+
+ TemplateList *result = TemplateList::alloc();
+ TemplateVariant item;
+ for (it->toFirst();(it->current(item));it->toNext())
+ {
+ //printf("item type=%s\n",item.typeAsString());
+ TemplateStructIntf *s = item.toStruct();
+ if (s)
+ {
+ TemplateVariant value = s->get(args.toString());
+ //printf("value type=%s\n",value.typeAsString());
+ if (value.toBool())
+ {
+ //printf("keeping it\n");
+ result->append(item);
+ }
+ else
+ {
+ //printf("Dropping it\n");
+ }
+ }
+ }
+ return result;
+ }
+ return v;
+ }
+};
+
+//-----------------------------------------------------------------------------
+
/** @brief The implementation of the "list" filter */
class FilterList
{
@@ -671,7 +748,7 @@ class FilterList
{
if (v.isValid())
{
- if (v.type()==TemplateVariant::List) // input is already a list
+ if (v.isList()) // input is already a list
{
return v;
}
@@ -694,7 +771,7 @@ class FilterTexLabel
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
{
- if (v.isValid() && (v.type()==TemplateVariant::String))
+ if (v.isValid() && (v.isString()))
{
return TemplateVariant(latexEscapeLabelName(v.toString()),TRUE);
}
@@ -713,7 +790,7 @@ class FilterTexIndex
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
{
- if (v.isValid() && (v.type()==TemplateVariant::String))
+ if (v.isValid() && (v.isString()))
{
return TemplateVariant(latexEscapeIndexChars(v.toString()),TRUE);
}
@@ -732,8 +809,8 @@ class FilterAppend
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &arg)
{
- if ((v.type()==TemplateVariant::String || v.type()==TemplateVariant::Integer) &&
- (arg.type()==TemplateVariant::String || arg.type()==TemplateVariant::Integer))
+ if ((v.isString() || v.isInt()) &&
+ (arg.isString() || arg.isInt()))
{
return TemplateVariant(v.toString() + arg.toString());
}
@@ -752,8 +829,8 @@ class FilterPrepend
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &arg)
{
- if ((v.type()==TemplateVariant::String || v.type()==TemplateVariant::Integer) &&
- arg.type()==TemplateVariant::String)
+ if ((v.isString() || v.isInt()) &&
+ arg.isString())
{
return TemplateVariant(arg.toString() + v.toString());
}
@@ -776,11 +853,11 @@ class FilterLength
{
return TemplateVariant();
}
- if (v.type()==TemplateVariant::List)
+ if (v.isList())
{
return TemplateVariant((int)v.toList()->count());
}
- else if (v.type()==TemplateVariant::String)
+ else if (v.isString())
{
return TemplateVariant((int)v.toString().length());
}
@@ -803,7 +880,7 @@ class FilterDefault
{
return arg;
}
- else if (v.type()==TemplateVariant::String && v.toString().isEmpty())
+ else if (v.isString() && v.toString().isEmpty())
{
return arg;
}
@@ -822,7 +899,7 @@ class FilterFlatten
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
{
- if (!v.isValid() || v.type()!=TemplateVariant::List)
+ if (!v.isValid() || !v.isList())
{
return v;
}
@@ -835,7 +912,7 @@ class FilterFlatten
}
private:
- static void flatten(TemplateListIntf *tree,TemplateList *list)
+ static void flatten(const TemplateListIntf *tree,TemplateList *list)
{
TemplateListIntf::ConstIterator *it = tree->createIterator();
TemplateVariant item;
@@ -847,7 +924,7 @@ class FilterFlatten
list->append(item);
// if s has "children" then recurse into the children
TemplateVariant children = s->get("children");
- if (children.isValid() && children.type()==TemplateVariant::List)
+ if (children.isValid() && children.isList())
{
flatten(children.toList(),list);
}
@@ -872,50 +949,42 @@ class FilterListSort
QCString key;
TemplateVariant value;
};
- class SortList : public QList<ListElem>
- {
- public:
- SortList() { setAutoDelete(TRUE); }
- private:
- int compareValues(const ListElem *item1,const ListElem *item2) const
- {
- return qstrcmp(item1->key,item2->key);
- }
- };
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &args)
{
- if (v.type()==TemplateVariant::List && args.type()==TemplateVariant::String)
+ if (v.isList() && args.isString())
{
- //printf("FilterListSort::apply: v=%s args=%s\n",v.toString().data(),args.toString().data());
+ //printf("FilterListSort::apply: v=%s args=%s\n",qPrint(v.toString()),qPrint(args.toString()));
TemplateListIntf::ConstIterator *it = v.toList()->createIterator();
TemplateVariant item;
TemplateList *result = TemplateList::alloc();
// create list of items based on v using the data in args as a sort key
+ using SortList = std::vector<ListElem>;
SortList sortList;
+ sortList.reserve(v.toList()->count());
for (it->toFirst();(it->current(item));it->toNext())
{
TemplateStructIntf *s = item.toStruct();
if (s)
{
QCString sortKey = determineSortKey(s,args.toString());
- sortList.append(new ListElem(sortKey,item));
- //printf("sortKey=%s\n",sortKey.data());
+ sortList.emplace_back(sortKey,item);
+ //printf("sortKey=%s\n",qPrint(sortKey));
}
}
delete it;
// sort the list
- sortList.sort();
+ std::sort(sortList.begin(),
+ sortList.end(),
+ [](const auto &lhs,const auto &rhs) { return lhs.key < rhs.key; });
// add sorted items to the result list
- QListIterator<ListElem> sit(sortList);
- ListElem *elem;
- for (sit.toFirst();(elem=sit.current());++sit)
+ for (const auto &elem : sortList)
{
- result->append(elem->value);
+ result->append(elem.value);
}
return result;
}
@@ -935,7 +1004,7 @@ class FilterListSort
{
QCString var = arg.mid(i+2,j-i-2);
TemplateVariant val=s->get(var);
- //printf("found argument %s value=%s\n",var.data(),val.toString().data());
+ //printf("found argument %s value=%s\n",qPrint(var),qPrint(val.toString()));
result+=val.toString();
p=j+2;
}
@@ -960,58 +1029,50 @@ class FilterGroupBy
QCString key;
TemplateVariant value;
};
- class SortList : public QList<ListElem>
- {
- public:
- SortList() { setAutoDelete(TRUE); }
- private:
- int compareValues(const ListElem *item1,const ListElem *item2) const
- {
- return qstrcmp(item1->key,item2->key);
- }
- };
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &args)
{
- if (v.type()==TemplateVariant::List && args.type()==TemplateVariant::String)
+ if (v.isList() && args.isString())
{
- //printf("FilterListSort::apply: v=%s args=%s\n",v.toString().data(),args.toString().data());
+ //printf("FilterListSort::apply: v=%s args=%s\n",qPrint(v.toString()),qPrint(args.toString()));
TemplateListIntf::ConstIterator *it = v.toList()->createIterator();
TemplateVariant item;
TemplateList *result = TemplateList::alloc();
// create list of items based on v using the data in args as a sort key
+ using SortList = std::vector<ListElem>;
SortList sortList;
+ sortList.reserve(v.toList()->count());
for (it->toFirst();(it->current(item));it->toNext())
{
TemplateStructIntf *s = item.toStruct();
if (s)
{
QCString sortKey = determineSortKey(s,args.toString());
- sortList.append(new ListElem(sortKey,item));
- //printf("sortKey=%s\n",sortKey.data());
+ sortList.emplace_back(sortKey,item);
+ //printf("sortKey=%s\n",qPrint(sortKey));
}
}
delete it;
// sort the list
- sortList.sort();
+ std::sort(sortList.begin(),
+ sortList.end(),
+ [](const auto &lhs,const auto &rhs) { return lhs.key < rhs.key; });
// add sorted items to the result list
- QListIterator<ListElem> sit(sortList);
- ListElem *elem;
TemplateList *groupList=0;
QCString prevKey;
- for (sit.toFirst();(elem=sit.current());++sit)
+ for (const auto &elem : sortList)
{
- if (groupList==0 || elem->key!=prevKey)
+ if (groupList==0 || elem.key!=prevKey)
{
groupList = TemplateList::alloc();
result->append(groupList);
- prevKey = elem->key;
+ prevKey = elem.key;
}
- groupList->append(elem->value);
+ groupList->append(elem.value);
}
return result;
}
@@ -1034,7 +1095,7 @@ class FilterRelative
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
{
- if (v.isValid() && v.type()==TemplateVariant::String && v.toString().left(2)=="..")
+ if (v.isValid() && v.isString() && v.toString().left(2)=="..")
{
return TRUE;
}
@@ -1053,11 +1114,11 @@ class FilterPaginate
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &args)
{
- if (v.isValid() && v.type()==TemplateVariant::List &&
- args.isValid() && args.type()==TemplateVariant::Integer)
+ if (v.isValid() && v.isList() &&
+ args.isValid() && args.isInt())
{
int pageSize = args.toInt();
- TemplateListIntf *list = v.toList();
+ const TemplateListIntf *list = v.toList();
TemplateList *result = TemplateList::alloc();
TemplateListIntf::ConstIterator *it = list->createIterator();
TemplateVariant item;
@@ -1096,118 +1157,90 @@ class FilterAlphaIndex
private:
struct ListElem
{
- ListElem(uint k,const TemplateVariant &v) : key(k), value(v) {}
- uint key;
+ ListElem(std::string k,const TemplateVariant &v) : key(k), value(v) {}
+ std::string key;
TemplateVariant value;
};
- class SortList : public QList<ListElem>
+ static QCString keyToLabel(const char *startLetter)
{
- public:
- SortList() { setAutoDelete(TRUE); }
- private:
- int compareValues(const ListElem *item1,const ListElem *item2) const
- {
- return item1->key-item2->key;
- }
- };
- static QCString keyToLetter(uint startLetter)
- {
- return QString(QChar(startLetter)).utf8();
- }
- static QCString keyToLabel(uint startLetter)
- {
- char s[11]; // 0x12345678 + '\0'
- if ((startLetter>='0' && startLetter<='9') ||
- (startLetter>='a' && startLetter<='z') ||
- (startLetter>='A' && startLetter<='Z'))
+ //printf(">keyToLabel(%s)\n",qPrint(startLetter));
+ const char *p = startLetter;
+ char c = *p;
+ QCString result;
+ if (c<127 && c>31) // printable ASCII character
{
- int i=0;
- if (startLetter>='0' && startLetter<='9') s[i++] = 'x';
- s[i++]=(char)tolower((char)startLetter);
- s[i++]=0;
+ result+=c;
}
else
{
+ result="0x";
const char hex[]="0123456789abcdef";
- int i=0;
- s[i++]='x';
- if (startLetter>(1<<24)) // 4 byte character
- {
- s[i++]=hex[(startLetter>>28)&0xf];
- s[i++]=hex[(startLetter>>24)&0xf];
- }
- if (startLetter>(1<<16)) // 3 byte character
- {
- s[i++]=hex[(startLetter>>20)&0xf];
- s[i++]=hex[(startLetter>>16)&0xf];
- }
- if (startLetter>(1<<8)) // 2 byte character
+ while ((c=*p++))
{
- s[i++]=hex[(startLetter>>12)&0xf];
- s[i++]=hex[(startLetter>>8)&0xf];
+ result+=hex[((unsigned char)c)>>4];
+ result+=hex[((unsigned char)c)&0xf];
}
- // one byte character
- s[i++]=hex[(startLetter>>4)&0xf];
- s[i++]=hex[(startLetter>>0)&0xf];
- s[i++]=0;
}
- return s;
+ //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 getUtf8CodeToUpper(v.toString(),index);
+ return convertUTF8ToUpper(getUTF8CharAt(v.toString().str(),index));
}
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &args)
{
- if (v.type()==TemplateVariant::List && args.type()==TemplateVariant::String)
+ if (v.isList() && args.isString())
{
- //printf("FilterListSort::apply: v=%s args=%s\n",v.toString().data(),args.toString().data());
+ //printf("FilterListSort::apply: v=%s args=%s\n",qPrint(v.toString()),qPrint(args.toString()));
TemplateListIntf::ConstIterator *it = v.toList()->createIterator();
TemplateVariant item;
TemplateList *result = TemplateList::alloc();
// create list of items based on v using the data in args as a sort key
+ using SortList = std::vector<ListElem>;
SortList sortList;
+ sortList.reserve(v.toList()->count());
for (it->toFirst();(it->current(item));it->toNext())
{
TemplateStructIntf *s = item.toStruct();
if (s)
{
- uint sortKey = determineSortKey(s,args.toString());
- sortList.append(new ListElem(sortKey,item));
- //printf("sortKey=%s\n",sortKey.data());
+ std::string sortKey = determineSortKey(s,args.toString());
+ sortList.emplace_back(sortKey,item);
+ //printf("sortKey=%s\n",qPrint(sortKey));
}
}
delete it;
// sort the list
- sortList.sort();
+ std::sort(sortList.begin(),
+ sortList.end(),
+ [](const auto &lhs,const auto &rhs) { return lhs.key < rhs.key; });
// create an index from the sorted list
- uint letter=0;
- QListIterator<ListElem> sit(sortList);
- ListElem *elem;
+ std::string letter;
TemplateStruct *indexNode = 0;
TemplateList *indexList = 0;
- for (sit.toFirst();(elem=sit.current());++sit)
+ for (const auto &elem : sortList)
{
- if (letter!=elem->key || indexNode==0)
+ if (letter!=elem.key || indexNode==0)
{
// create new indexNode
indexNode = TemplateStruct::alloc();
indexList = TemplateList::alloc();
- indexNode->set("letter", keyToLetter(elem->key));
- indexNode->set("label", keyToLabel(elem->key));
+ indexNode->set("letter", elem.key);
+ indexNode->set("label", keyToLabel(elem.key.c_str()));
indexNode->set("items",indexList);
result->append(indexNode);
- letter=elem->key;
+ letter=elem.key;
}
- indexList->append(elem->value);
+ indexList->append(elem.value);
}
return result;
}
@@ -1223,7 +1256,7 @@ class FilterStripPath
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
{
- if (!v.isValid() || v.type()!=TemplateVariant::String)
+ if (!v.isValid() || !v.isString())
{
return v;
}
@@ -1250,7 +1283,7 @@ class FilterNoWrap
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
{
- if (!v.isValid() || v.type()!=TemplateVariant::String)
+ if (!v.isValid() || !v.isString())
{
return v;
}
@@ -1271,7 +1304,7 @@ class FilterDivisibleBy
{
return TemplateVariant();
}
- if (v.type()==TemplateVariant::Integer && n.type()==TemplateVariant::Integer)
+ if (v.isInt() && n.isInt())
{
int ni = n.toInt();
if (ni>0)
@@ -1298,7 +1331,7 @@ class FilterIsRelativeURL
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
{
- if (v.isValid() && v.type()==TemplateVariant::String)
+ if (v.isValid() && v.isString())
{
QCString s = v.toString();
if (!s.isEmpty() && s.at(0)=='!') return TRUE;
@@ -1315,7 +1348,7 @@ class FilterIsAbsoluteURL
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
{
- if (v.isValid() && v.type()==TemplateVariant::String)
+ if (v.isValid() && v.isString())
{
QCString s = v.toString();
if (!s.isEmpty() && s.at(0)=='^') return TRUE;
@@ -1326,6 +1359,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.isString())
+ {
+ 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.isString())
+ {
+ 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.isString())
+ {
+ 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
@@ -1336,7 +1435,7 @@ class FilterDecodeURL
public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
{
- if (v.isValid() && v.type()==TemplateVariant::String)
+ if (v.isValid() && v.isString())
{
QCString s = v.toString();
if (!s.isEmpty() && (s.at(0)=='^' || s.at(0)=='!'))
@@ -1366,11 +1465,11 @@ class TemplateFilterFactory
TemplateVariant apply(const QCString &name,const TemplateVariant &v,const TemplateVariant &arg, bool &ok)
{
- FilterFunction *func = (FilterFunction*)m_registry.find(name);
- if (func)
+ auto it = m_registry.find(name.str());
+ if (it!=m_registry.end())
{
ok=TRUE;
- return (*func)(v,arg);
+ return it->second(v,arg);
}
else
{
@@ -1381,7 +1480,7 @@ class TemplateFilterFactory
void registerFilter(const QCString &name,FilterFunction *func)
{
- m_registry.insert(name,(void*)func);
+ m_registry.insert(std::make_pair(name.str(),func));
}
/** @brief Helper class for registering a filter function */
@@ -1395,15 +1494,20 @@ class TemplateFilterFactory
};
private:
- QDict<void> m_registry;
+ std::unordered_map<std::string,FilterFunction*> m_registry;
};
// 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<FilterKeep> fKeep("keep");
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");
@@ -1434,6 +1538,8 @@ class ExprAst
virtual TemplateVariant resolve(TemplateContext *) { return TemplateVariant(); }
};
+using ExprAstList = std::vector< std::unique_ptr<ExprAst> >;
+
/** @brief Class representing a number in the AST */
class ExprAstNumber : public ExprAst
{
@@ -1450,8 +1556,8 @@ class ExprAstNumber : public ExprAst
class ExprAstVariable : public ExprAst
{
public:
- ExprAstVariable(const char *name) : m_name(name)
- { TRACE(("ExprAstVariable(%s)\n",name)); }
+ ExprAstVariable(const QCString &name) : m_name(name)
+ { TRACE(("ExprAstVariable(%s)\n",name.data())); }
const QCString &name() const { return m_name; }
virtual TemplateVariant resolve(TemplateContext *c)
{
@@ -1459,7 +1565,7 @@ class ExprAstVariable : public ExprAst
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (!v.isValid())
{
- if (ci) ci->warn(ci->templateName(),ci->line(),"undefined variable '%s' in expression",m_name.data());
+ if (ci) ci->warn(ci->templateName(),ci->line(),"undefined variable '%s' in expression",qPrint(m_name));
}
return v;
}
@@ -1470,10 +1576,9 @@ class ExprAstVariable : public ExprAst
class ExprAstFunctionVariable : public ExprAst
{
public:
- ExprAstFunctionVariable(ExprAst *var,const QList<ExprAst> &args)
- : m_var(var), m_args(args)
+ ExprAstFunctionVariable(ExprAst *var, ExprAstList &&args)
+ : m_var(var), m_args(std::move(args))
{ TRACE(("ExprAstFunctionVariable()\n"));
- m_args.setAutoDelete(TRUE);
}
~ExprAstFunctionVariable()
{
@@ -1482,13 +1587,13 @@ class ExprAstFunctionVariable : public ExprAst
virtual TemplateVariant resolve(TemplateContext *c)
{
std::vector<TemplateVariant> args;
- for (uint i=0;i<m_args.count();i++)
+ for (const auto &exprArg : m_args)
{
- TemplateVariant v = m_args.at(i)->resolve(c);
+ TemplateVariant v = exprArg->resolve(c);
args.push_back(v);
}
TemplateVariant v = m_var->resolve(c);
- if (v.type()==TemplateVariant::Function)
+ if (v.isFunction())
{
v = v.call(args);
}
@@ -1496,29 +1601,29 @@ class ExprAstFunctionVariable : public ExprAst
}
private:
ExprAst *m_var = 0;
- QList<ExprAst> m_args;
+ ExprAstList m_args;
};
/** @brief Class representing a filter in the AST */
class ExprAstFilter : public ExprAst
{
public:
- ExprAstFilter(const char *name,ExprAst *arg) : m_name(name), m_arg(arg)
- { TRACE(("ExprAstFilter(%s)\n",name)); }
+ ExprAstFilter(const QCString &name,ExprAst *arg) : m_name(name), m_arg(arg)
+ { TRACE(("ExprAstFilter(%s)\n",name.data())); }
~ExprAstFilter() { delete m_arg; }
const QCString &name() const { return m_name; }
TemplateVariant apply(const TemplateVariant &v,TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return v; // should not happen
- TRACE(("Applying filter '%s' to '%s' (type=%d)\n",m_name.data(),v.toString().data(),v.type()));
+ TRACE(("Applying filter '%s' to '%s' (type=%d)\n",qPrint(m_name),qPrint(v.toString()),v.type()));
TemplateVariant arg;
if (m_arg) arg = m_arg->resolve(c);
bool ok;
TemplateVariant result = TemplateFilterFactory::instance()->apply(m_name,v,arg,ok);
if (!ok)
{
- ci->warn(ci->templateName(),ci->line(),"unknown filter '%s'",m_name.data());
+ ci->warn(ci->templateName(),ci->line(),"unknown filter '%s'",qPrint(m_name));
}
return result;
}
@@ -1548,8 +1653,8 @@ class ExprAstFilterAppl : public ExprAst
class ExprAstLiteral : public ExprAst
{
public:
- ExprAstLiteral(const char *lit) : m_literal(lit)
- { TRACE(("ExprAstLiteral(%s)\n",lit)); }
+ ExprAstLiteral(const QCString &lit) : m_literal(lit)
+ { TRACE(("ExprAstLiteral(%s)\n",lit.data())); }
const QCString &literal() const { return m_literal; }
virtual TemplateVariant resolve(TemplateContext *) { return TemplateVariant(m_literal); }
private:
@@ -1616,7 +1721,7 @@ class ExprAstBinary : public ExprAst
case Operator::NotEqual:
return TemplateVariant(!(lhs == rhs));
case Operator::Less:
- if (lhs.type()==TemplateVariant::String && rhs.type()==TemplateVariant::String)
+ if (lhs.isString() && rhs.isString())
{
return lhs.toString()<rhs.toString();
}
@@ -1625,7 +1730,7 @@ class ExprAstBinary : public ExprAst
return lhs.toInt()<rhs.toInt();
}
case Operator::Greater:
- if (lhs.type()==TemplateVariant::String && rhs.type()==TemplateVariant::String)
+ if (lhs.isString() && rhs.isString())
{
return !(lhs.toString()<rhs.toString());
}
@@ -1634,7 +1739,7 @@ class ExprAstBinary : public ExprAst
return lhs.toInt()>rhs.toInt();
}
case Operator::LessEqual:
- if (lhs.type()==TemplateVariant::String && rhs.type()==TemplateVariant::String)
+ if (lhs.isString() && rhs.isString())
{
return lhs.toString()==rhs.toString() || lhs.toString()<rhs.toString();
}
@@ -1643,7 +1748,7 @@ class ExprAstBinary : public ExprAst
return lhs.toInt()<=rhs.toInt();
}
case Operator::GreaterEqual:
- if (lhs.type()==TemplateVariant::String && rhs.type()==TemplateVariant::String)
+ if (lhs.isString() && rhs.isString())
{
return lhs.toString()==rhs.toString() || !(lhs.toString()<rhs.toString());
}
@@ -1708,7 +1813,7 @@ class TemplateNode
TemplateNode(TemplateNode *parent) : m_parent(parent) {}
virtual ~TemplateNode() {}
- virtual void render(FTextStream &ts, TemplateContext *c) = 0;
+ virtual void render(TextStream &ts, TemplateContext *c) = 0;
TemplateNode *parent() { return m_parent; }
@@ -1718,25 +1823,59 @@ class TemplateNode
//----------------------------------------------------------
+/** @brief Class representing a lexical token in a template */
+class TemplateToken
+{
+ public:
+ enum Type { Text, Variable, Block };
+ TemplateToken(Type t,const QCString &d,int l) : type(t), data(d), line(l) {}
+ Type type = Text;
+ QCString data;
+ int line = 0;
+};
+
+using TemplateTokenPtr = std::unique_ptr<TemplateToken>;
+using TemplateTokenStream = std::deque< TemplateTokenPtr >;
+
+//----------------------------------------------------------
+
+/** @brief Class representing a list of AST nodes in a template */
+class TemplateNodeList : public std::vector< std::unique_ptr<TemplateNode> >
+{
+ public:
+ void render(TextStream &ts,TemplateContext *c)
+ {
+ TRACE(("{TemplateNodeList::render\n"));
+ for (const auto &tn : *this)
+ {
+ tn->render(ts,c);
+ }
+ TRACE(("}TemplateNodeList::render\n"));
+ }
+};
+
+//----------------------------------------------------------
+
/** @brief Parser for templates */
class TemplateParser
{
public:
TemplateParser(const TemplateEngine *engine,
- const QCString &templateName,QList<TemplateToken> &tokens);
- void parse(TemplateNode *parent,int line,const QStrList &stopAt,
- QList<TemplateNode> &nodes);
+ const QCString &templateName,
+ TemplateTokenStream &tokens);
+ void parse(TemplateNode *parent,int line,const StringVector &stopAt,
+ TemplateNodeList &nodes);
bool hasNextToken() const;
- TemplateToken *takeNextToken();
+ TemplateTokenPtr takeNextToken();
void removeNextToken();
- void prependToken(const TemplateToken *token);
+ void prependToken(TemplateTokenPtr &&token);
const TemplateToken *currentToken() const;
QCString templateName() const { return m_templateName; }
- void warn(const char *fileName,int line,const char *fmt,...) const;
+ void warn(const QCString &fileName,int line,const char *fmt,...) const;
private:
const TemplateEngine *m_engine = 0;
QCString m_templateName;
- QList<TemplateToken> &m_tokens;
+ TemplateTokenStream &m_tokens;
};
//--------------------------------------------------------------------
@@ -1754,10 +1893,10 @@ class ExpressionParser
{
}
- ExprAst *parse(const char *expr)
+ ExprAst *parse(const QCString &expr)
{
- if (expr==0) return 0;
- m_tokenStream = expr;
+ if (expr.isEmpty()) return 0;
+ m_tokenStream = expr.data();
getNextToken();
return parseExpression();
}
@@ -1978,6 +2117,7 @@ class ExpressionParser
{
warn(m_parser->templateName(),m_line,"unexpected operator '%s' in expression",
Operator::toString(m_curToken.op));
+ abort();
}
break;
default:
@@ -1998,7 +2138,7 @@ class ExpressionParser
ExprAst *parseIdentifier()
{
- TRACE(("{parseIdentifier(%s)\n",m_curToken.id.data()));
+ TRACE(("{parseIdentifier(%s)\n",qPrint(m_curToken.id)));
ExprAst *id = new ExprAstVariable(m_curToken.id);
getNextToken();
TRACE(("}parseIdentifier()\n"));
@@ -2007,7 +2147,7 @@ class ExpressionParser
ExprAst *parseLiteral()
{
- TRACE(("{parseLiteral(%s)\n",m_curToken.id.data()));
+ TRACE(("{parseLiteral(%s)\n",qPrint(m_curToken.id)));
ExprAst *expr = new ExprAstLiteral(m_curToken.id);
getNextToken();
TRACE(("}parseLiteral()\n"));
@@ -2016,7 +2156,7 @@ class ExpressionParser
ExprAst *parseIdentifierOptionalArgs()
{
- TRACE(("{parseIdentifierOptionalArgs(%s)\n",m_curToken.id.data()));
+ TRACE(("{parseIdentifierOptionalArgs(%s)\n",qPrint(m_curToken.id)));
ExprAst *expr = parseIdentifier();
if (expr)
{
@@ -2024,17 +2164,15 @@ class ExpressionParser
m_curToken.op==Operator::Colon)
{
getNextToken();
- ExprAst *argExpr = parsePrimaryExpression();
- QList<ExprAst> args;
- args.append(argExpr);
+ ExprAstList args;
+ args.push_back(std::unique_ptr<ExprAst>(parsePrimaryExpression()));
while (m_curToken.type==ExprToken::Operator &&
m_curToken.op==Operator::Comma)
{
getNextToken();
- argExpr = parsePrimaryExpression();
- args.append(argExpr);
+ args.push_back(std::unique_ptr<ExprAst>(parsePrimaryExpression()));
}
- expr = new ExprAstFunctionVariable(expr,args);
+ expr = new ExprAstFunctionVariable(expr,std::move(args));
}
}
TRACE(("}parseIdentifierOptionalArgs()\n"));
@@ -2062,7 +2200,7 @@ class ExpressionParser
ExprAstFilter *parseFilter()
{
- TRACE(("{parseFilter(%s)\n",m_curToken.id.data()));
+ TRACE(("{parseFilter(%s)\n",qPrint(m_curToken.id)));
QCString filterName = m_curToken.id;
getNextToken();
ExprAst *argExpr=0;
@@ -2272,8 +2410,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,m_curToken.id.data()));
+ 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;
@@ -2287,42 +2425,6 @@ class ExpressionParser
//----------------------------------------------------------
-/** @brief Class representing a lexical token in a template */
-class TemplateToken
-{
- public:
- enum Type { Text, Variable, Block };
- TemplateToken(Type t,const char *d,int l) : type(t), data(d), line(l) {}
- Type type = Text;
- QCString data;
- int line = 0;
-};
-
-//----------------------------------------------------------
-
-/** @brief Class representing a list of AST nodes in a template */
-class TemplateNodeList : public QList<TemplateNode>
-{
- public:
- TemplateNodeList()
- {
- setAutoDelete(TRUE);
- }
- void render(FTextStream &ts,TemplateContext *c)
- {
- TRACE(("{TemplateNodeList::render\n"));
- QListIterator<TemplateNode> it(*this);
- TemplateNode *tn=0;
- for (it.toFirst();(tn=it.current());++it)
- {
- tn->render(ts,c);
- }
- TRACE(("}TemplateNodeList::render\n"));
- }
-};
-
-//----------------------------------------------------------
-
/** @brief Internal class representing the implementation of a template */
class TemplateImpl : public TemplateNode, public Template
{
@@ -2330,7 +2432,7 @@ class TemplateImpl : public TemplateNode, public Template
TemplateImpl(TemplateEngine *e,const QCString &name,const QCString &data,
const QCString &extension);
~TemplateImpl();
- void render(FTextStream &ts, TemplateContext *c);
+ void render(TextStream &ts, TemplateContext *c);
TemplateEngine *engine() const { return m_engine; }
TemplateBlockContext *blockContext() { return &m_blockContext; }
@@ -2351,7 +2453,8 @@ class TemplateStructWeakRef : public TemplateStructIntf
{
public:
TemplateStructWeakRef(TemplateStructIntf *ref) : m_ref(ref), m_refCount(0) {}
- virtual TemplateVariant get(const char *name) const { return m_ref->get(name); }
+ 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:
@@ -2365,9 +2468,6 @@ TemplateContextImpl::TemplateContextImpl(const TemplateEngine *e)
: m_engine(e), m_templateName("<unknown>"), m_line(1), m_activeEscapeIntf(0),
m_spacelessIntf(0), m_spacelessEnabled(FALSE), m_tabbingEnabled(FALSE), m_indices(TemplateStruct::alloc())
{
- m_indexStacks.setAutoDelete(TRUE);
- m_contextStack.setAutoDelete(TRUE);
- m_escapeIntfDict.setAutoDelete(TRUE);
m_fromUtf8 = (void*)(-1);
push();
set("index",m_indices.get());
@@ -2389,24 +2489,24 @@ void TemplateContextImpl::setEncoding(const QCString &templateName,int line,cons
m_encoding=enc;
if (!enc.isEmpty())
{
- m_fromUtf8 = portable_iconv_open(enc,"UTF-8");
+ m_fromUtf8 = portable_iconv_open(enc.data(),"UTF-8");
if (m_fromUtf8==(void*)(-1))
{
- warn(templateName,line,"unsupported character conversion: '%s'->'UTF-8'\n", enc.data());
+ warn(templateName,line,"unsupported character conversion: '%s'->'UTF-8'\n", qPrint(enc));
}
}
- //printf("TemplateContextImpl::setEncoding(%s)\n",enc.data());
+ //printf("TemplateContextImpl::setEncoding(%s)\n",qPrint(enc));
}
QCString TemplateContextImpl::recode(const QCString &s)
{
- //printf("TemplateContextImpl::recode(%s)\n",s.data());
+ //printf("TemplateContextImpl::recode(%s)\n",qPrint(s));
int iSize = s.length();
int oSize = iSize*4+1;
QCString output(oSize);
size_t iLeft = iSize;
size_t oLeft = oSize;
- char *iPtr = s.rawData();
+ const char *iPtr = s.data();
char *oPtr = output.rawData();
if (!portable_iconv(m_fromUtf8,&iPtr,&iLeft,&oPtr,&oLeft))
{
@@ -2421,14 +2521,32 @@ QCString TemplateContextImpl::recode(const QCString &s)
}
}
-void TemplateContextImpl::set(const char *name,const TemplateVariant &v)
+void TemplateContextImpl::set(const QCString &name,const TemplateVariant &v)
{
- TemplateVariant *pv = m_contextStack.getFirst()->find(name);
- if (pv)
+ auto &ctx = m_contextStack.front();
+ auto it = ctx.find(name.str());
+ if (it!=ctx.end())
{
- m_contextStack.getFirst()->remove(name);
+ ctx.erase(it);
}
- m_contextStack.getFirst()->insert(name,new 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
@@ -2445,15 +2563,15 @@ TemplateVariant TemplateContextImpl::get(const QCString &name) const
QCString propName = name.mid(i+1);
while (!propName.isEmpty())
{
- //printf("getPrimary(%s) type=%d:%s\n",objName.data(),v.type(),v.toString().data());
- if (v.type()==TemplateVariant::Struct)
+ //printf("getPrimary(%s) type=%zu:%s\n",qPrint(objName),v.type(),qPrint(v.toString()));
+ if (v.isStruct())
{
i = propName.find(".");
int l = i==-1 ? propName.length() : i;
v = v.toStruct()->get(propName.left(l));
if (!v.isValid())
{
- warn(m_templateName,m_line,"requesting non-existing property '%s' for object '%s'",propName.left(l).data(),objName.data());
+ warn(m_templateName,m_line,"requesting non-existing property '%s' for object '%s'",qPrint(propName.left(l)),qPrint(objName));
}
if (i!=-1)
{
@@ -2465,7 +2583,7 @@ TemplateVariant TemplateContextImpl::get(const QCString &name) const
propName.resize(0);
}
}
- else if (v.type()==TemplateVariant::List)
+ else if (v.isList())
{
i = propName.find(".");
int l = i==-1 ? propName.length() : i;
@@ -2477,7 +2595,7 @@ TemplateVariant TemplateContextImpl::get(const QCString &name) const
}
else
{
- warn(m_templateName,m_line,"list index '%s' is not valid",propName.data());
+ warn(m_templateName,m_line,"list index '%s' is not valid",qPrint(propName));
break;
}
if (i!=-1)
@@ -2491,7 +2609,7 @@ TemplateVariant TemplateContextImpl::get(const QCString &name) const
}
else
{
- warn(m_templateName,m_line,"using . on an object '%s' is not an struct or list",objName.data());
+ warn(m_templateName,m_line,"using . on an object '%s' is not an struct or list",qPrint(objName));
return TemplateVariant();
}
}
@@ -2501,12 +2619,13 @@ TemplateVariant TemplateContextImpl::get(const QCString &name) const
const TemplateVariant *TemplateContextImpl::getRef(const QCString &name) const
{
- QListIterator< QDict<TemplateVariant> > it(m_contextStack);
- QDict<TemplateVariant> *dict;
- for (it.toFirst();(dict=it.current());++it)
+ for (const auto &ctx : m_contextStack)
{
- TemplateVariant *v = dict->find(name);
- if (v) return v;
+ auto it = ctx.find(name.str());
+ if (it!=ctx.end())
+ {
+ return &it->second;
+ }
}
return 0; // not found
}
@@ -2519,17 +2638,19 @@ TemplateVariant TemplateContextImpl::getPrimary(const QCString &name) const
void TemplateContextImpl::push()
{
- QDict<TemplateVariant> *dict = new QDict<TemplateVariant>;
- dict->setAutoDelete(TRUE);
- m_contextStack.prepend(dict);
+ m_contextStack.push_front(std::map<std::string,TemplateVariant>());
}
void TemplateContextImpl::pop()
{
- if (!m_contextStack.removeFirst())
+ if (m_contextStack.empty())
{
warn(m_templateName,m_line,"pop() called on empty context stack!\n");
}
+ else
+ {
+ m_contextStack.pop_front();
+ }
}
TemplateBlockContext *TemplateContextImpl::blockContext()
@@ -2537,7 +2658,7 @@ TemplateBlockContext *TemplateContextImpl::blockContext()
return &m_blockContext;
}
-void TemplateContextImpl::warn(const char *fileName,int line,const char *fmt,...) const
+void TemplateContextImpl::warn(const QCString &fileName,int line,const char *fmt,...) const
{
va_list args;
va_start(args,fmt);
@@ -2548,20 +2669,21 @@ void TemplateContextImpl::warn(const char *fileName,int line,const char *fmt,...
void TemplateContextImpl::openSubIndex(const QCString &indexName)
{
- //printf("TemplateContextImpl::openSubIndex(%s)\n",indexName.data());
- QStack<TemplateVariant> *stack = m_indexStacks.find(indexName);
- if (!stack || stack->isEmpty() || stack->top()->type()==TemplateVariant::List) // error: no stack yet or no entry
+ //printf("TemplateContextImpl::openSubIndex(%s)\n",qPrint(indexName));
+ auto kv = m_indexStacks.find(indexName.str());
+ if (kv==m_indexStacks.end() || kv->second.empty() || kv->second.top().isList()) // error: no stack yet or no entry
{
- warn(m_templateName,m_line,"opensubindex for index %s without preceding indexentry",indexName.data());
+ warn(m_templateName,m_line,"opensubindex for index %s without preceding indexentry",qPrint(indexName));
return;
}
// get the parent entry to add the list to
- TemplateStruct *entry = dynamic_cast<TemplateStruct*>(stack->top()->toStruct());
+ auto &stack = kv->second;
+ TemplateStruct *entry = dynamic_cast<TemplateStruct*>(stack.top().toStruct());
if (entry)
{
// add new list to the stack
TemplateList *list = TemplateList::alloc();
- stack->push(new TemplateVariant(list));
+ stack.emplace(list);
entry->set("children",list);
entry->set("is_leaf_node",false);
}
@@ -2569,36 +2691,37 @@ void TemplateContextImpl::openSubIndex(const QCString &indexName)
void TemplateContextImpl::closeSubIndex(const QCString &indexName)
{
- //printf("TemplateContextImpl::closeSubIndex(%s)\n",indexName.data());
- QStack<TemplateVariant> *stack = m_indexStacks.find(indexName);
- if (!stack || stack->count()<3)
+ //printf("TemplateContextImpl::closeSubIndex(%s)\n",qPrint(indexName));
+ auto kv = m_indexStacks.find(indexName.str());
+ if (kv==m_indexStacks.end() || kv->second.size()<3)
{
- warn(m_templateName,m_line,"closesubindex for index %s without matching open",indexName.data());
+ warn(m_templateName,m_line,"closesubindex for index %s without matching open",qPrint(indexName));
}
- else // stack->count()>=2
+ else
{
- if (stack->top()->type()==TemplateVariant::Struct)
+ auto &stack = kv->second; // stack.size()>2
+ if (stack.top().isStruct())
{
- delete stack->pop(); // pop struct
- delete stack->pop(); // pop list
+ stack.pop(); // pop struct
+ stack.pop(); // pop list
}
else // empty list! correct "is_left_node" attribute of the parent entry
{
- delete stack->pop(); // pop list
- TemplateStruct *entry = dynamic_cast<TemplateStruct*>(stack->top()->toStruct());
+ stack.pop(); // pop list
+ TemplateStruct *entry = dynamic_cast<TemplateStruct*>(stack.top().toStruct());
if (entry)
{
entry->set("is_leaf_node",true);
}
}
}
- //fprintf(stderr,"TemplateContextImpl::closeSubIndex(%s) end g_count=%d\n\n",indexName.data(),g_count);
+ //fprintf(stderr,"TemplateContextImpl::closeSubIndex(%s) end g_count=%d\n\n",qPrint(indexName),g_count);
}
static void getPathListFunc(TemplateStructIntf *entry,TemplateList *list)
{
TemplateVariant parent = entry->get("parent");
- if (parent.type()==TemplateVariant::Struct)
+ if (parent.isStruct())
{
getPathListFunc(parent.toStruct(),list);
}
@@ -2616,49 +2739,49 @@ static TemplateVariant getPathFunc(const void *ctx, const std::vector<TemplateVa
void TemplateContextImpl::addIndexEntry(const QCString &indexName,const std::vector<TemplateKeyValue> &arguments)
{
auto it = arguments.begin();
- //printf("TemplateContextImpl::addIndexEntry(%s)\n",indexName.data());
+ //printf("TemplateContextImpl::addIndexEntry(%s)\n",qPrint(indexName));
//while (it!=arguments.end())
//{
// printf(" key=%s value=%s\n",(*it).key.data(),(*it).value.toString().data());
// ++it;
//}
TemplateVariant parent(FALSE);
- QStack<TemplateVariant> *stack = m_indexStacks.find(indexName);
- if (!stack) // no stack yet, create it!
+ auto kv = m_indexStacks.find(indexName.str());
+ if (kv==m_indexStacks.end()) // no stack yet, create it!
{
- stack = new QStack<TemplateVariant>;
- stack->setAutoDelete(TRUE);
- m_indexStacks.insert(indexName,stack);
+ kv = m_indexStacks.insert(std::make_pair(indexName.str(),std::stack<TemplateVariant>())).first;
}
TemplateList *list = 0;
- if (stack->isEmpty()) // first item, create empty list and add it to the index
+ auto &stack = kv->second;
+ if (stack.empty()) // first item, create empty list and add it to the index
{
list = TemplateList::alloc();
- stack->push(new TemplateVariant(list));
+ stack.emplace(list);
m_indices->set(indexName,list); // make list available under index
}
else // stack not empty
{
- if (stack->top()->type()==TemplateVariant::Struct) // already an entry in the list
+ if (stack.top().isStruct()) // already an entry in the list
{
// remove current entry from the stack
- delete stack->pop();
+ stack.pop();
}
else // first entry after opensubindex
{
- ASSERT(stack->top()->type()==TemplateVariant::List);
+ ASSERT(stack.top().isList());
}
- if (stack->count()>1)
+ if (stack.size()>1)
{
- TemplateVariant *tmp = stack->pop();
+ TemplateVariant tmp = stack.top();
+ stack.pop();
// To prevent a cyclic dependency between parent and child which causes a memory
// leak, we wrap the parent into a weak reference version.
- parent = new TemplateStructWeakRef(stack->top()->toStruct());
- stack->push(tmp);
- ASSERT(parent.type()==TemplateVariant::Struct);
+ parent = new TemplateStructWeakRef(stack.top().toStruct());
+ stack.push(tmp);
+ ASSERT(parent.isStruct());
}
// get list to add new item
- list = dynamic_cast<TemplateList*>(stack->top()->toList());
+ list = dynamic_cast<TemplateList*>(stack.top().toList());
}
TemplateStruct *entry = TemplateStruct::alloc();
// add user specified fields to the entry
@@ -2678,9 +2801,9 @@ void TemplateContextImpl::addIndexEntry(const QCString &indexName,const std::vec
entry->set("first",list->count()==0);
entry->set("index",list->count());
entry->set("parent",parent);
- entry->set("path",TemplateVariant::Delegate::fromFunction(entry,getPathFunc));
+ entry->set("path",TemplateVariant::FunctionDelegate::fromFunction(entry,getPathFunc));
entry->set("last",true);
- stack->push(new TemplateVariant(entry));
+ stack.emplace(entry);
list->append(entry);
}
@@ -2696,11 +2819,11 @@ class TemplateNodeText : public TemplateNode
TRACE(("TemplateNodeText('%s')\n",replace(data,'\n',' ').data()));
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
- //printf("TemplateNodeText::render(%s) needsRecoding=%d ci=%p\n",m_data.data(),ci->needsRecoding(),ci);
+ //printf("TemplateNodeText::render(%s) needsRecoding=%d ci=%p\n",qPrint(m_data),ci->needsRecoding(),ci);
if (ci->spacelessEnabled())
{
if (ci->needsRecoding())
@@ -2737,12 +2860,12 @@ class TemplateNodeVariable : public TemplateNode
TemplateNodeVariable(TemplateParser *parser,TemplateNode *parent,int line,const QCString &var)
: TemplateNode(parent), m_templateName(parser->templateName()), m_line(line)
{
- TRACE(("TemplateNodeVariable(%s)\n",var.data()));
+ TRACE(("TemplateNodeVariable(%s)\n",qPrint(var)));
ExpressionParser expParser(parser,line);
m_var = expParser.parse(var);
if (m_var==0)
{
- parser->warn(m_templateName,line,"invalid expression '%s' for variable",var.data());
+ parser->warn(m_templateName,line,"invalid expression '%s' for variable",qPrint(var));
}
}
~TemplateNodeVariable()
@@ -2750,7 +2873,7 @@ class TemplateNodeVariable : public TemplateNode
delete m_var;
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -2758,7 +2881,7 @@ class TemplateNodeVariable : public TemplateNode
if (m_var)
{
TemplateVariant v = m_var->resolve(c);
- if (v.type()==TemplateVariant::Function)
+ if (v.isFunction())
{
v = v.call(std::vector<TemplateVariant>());
}
@@ -2791,7 +2914,6 @@ class TemplateNodeVariable : public TemplateNode
QCString m_templateName;
int m_line = 0;
ExprAst *m_var = 0;
- QList<ExprAst> m_args;
};
//----------------------------------------------------------
@@ -2821,36 +2943,35 @@ template<class T> class TemplateNodeCreator : public TemplateNode
return dynamic_cast<TemplateImpl*>(root);
}
protected:
- void mkpath(TemplateContextImpl *ci,const QCString &fileName)
+ void mkpath(TemplateContextImpl *ci,const std::string &fileName)
{
- int i=fileName.find('/');
- QCString outputDir = ci->outputDirectory();
- QDir d(outputDir);
+ size_t i=fileName.find('/');
+ std::string outputDir = ci->outputDirectory().str();
+ Dir d(outputDir);
if (!d.exists())
{
- QDir rootDir;
- rootDir.setPath(QDir::currentDirPath());
+ Dir rootDir;
if (!rootDir.mkdir(outputDir))
{
err("tag OUTPUT_DIRECTORY: Output directory '%s' does not "
- "exist and cannot be created\n",outputDir.data());
+ "exist and cannot be created\n",outputDir.c_str());
return;
}
d.setPath(outputDir);
}
- int j=0;
- while (i!=-1) // fileName contains path part
+ size_t j=0;
+ while (i!=std::string::npos) // fileName contains path part
{
if (d.exists())
{
- bool ok = d.mkdir(fileName.mid(j,i-j));
+ bool ok = d.mkdir(fileName.substr(j,i-j));
if (!ok)
{
- err("Failed to create directory '%s'\n",(fileName.mid(j,i-j)).data());
+ err("Failed to create directory '%s'\n",(fileName.substr(j,i-j)).c_str());
break;
}
- QCString dirName = outputDir+'/'+fileName.left(i);
- d = QDir(dirName);
+ std::string dirName = outputDir+'/'+fileName.substr(0,i);
+ d = Dir(dirName);
j = i+1;
}
i=fileName.find('/',i+1);
@@ -2869,67 +2990,59 @@ class TemplateNodeIf : public TemplateNodeCreator<TemplateNodeIf>
TemplateNodeIf(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data) :
TemplateNodeCreator<TemplateNodeIf>(parser,parent,line)
{
- m_ifGuardedNodes.setAutoDelete(TRUE);
- TRACE(("{TemplateNodeIf(%s)\n",data.data()));
+ TRACE(("{TemplateNodeIf(%s)\n",qPrint(data)));
if (data.isEmpty())
{
parser->warn(m_templateName,line,"missing argument for if tag");
}
- QStrList stopAt;
- stopAt.append("endif");
- stopAt.append("elif");
- stopAt.append("else");
+ StringVector stopAt = { "endif", "elif", "else" };
// if 'nodes'
{
- GuardedNodes *guardedNodes = new GuardedNodes;
+ m_ifGuardedNodes.push_back(std::make_unique<GuardedNodes>());
+ auto &guardedNodes = m_ifGuardedNodes.back();
ExpressionParser ex(parser,line);
guardedNodes->line = line;
guardedNodes->guardAst = ex.parse(data);
parser->parse(this,line,stopAt,guardedNodes->trueNodes);
- m_ifGuardedNodes.append(guardedNodes);
}
- TemplateToken *tok = parser->takeNextToken();
+ auto tok = parser->takeNextToken();
// elif 'nodes'
while (tok && tok->data.left(5)=="elif ")
{
+ m_ifGuardedNodes.push_back(std::make_unique<GuardedNodes>());
+ auto &guardedNodes = m_ifGuardedNodes.back();
ExpressionParser ex(parser,line);
- GuardedNodes *guardedNodes = new GuardedNodes;
guardedNodes->line = tok->line;
guardedNodes->guardAst = ex.parse(tok->data.mid(5));
parser->parse(this,tok->line,stopAt,guardedNodes->trueNodes);
- m_ifGuardedNodes.append(guardedNodes);
// proceed to the next token
- delete tok;
tok = parser->takeNextToken();
}
// else 'nodes'
if (tok && tok->data=="else")
{
- stopAt.removeLast(); // remove "else"
- stopAt.removeLast(); // remove "elif"
+ stopAt.pop_back(); // remove "else"
+ stopAt.pop_back(); // remove "elif"
parser->parse(this,line,stopAt,m_falseNodes);
parser->removeNextToken(); // skip over endif
}
- delete tok;
- TRACE(("}TemplateNodeIf(%s)\n",data.data()));
+ TRACE(("}TemplateNodeIf(%s)\n",qPrint(data)));
}
~TemplateNodeIf()
{
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
ci->setLocation(m_templateName,m_line);
//printf("TemplateNodeIf::render #trueNodes=%d #falseNodes=%d\n",m_trueNodes.count(),m_falseNodes.count());
bool processed=FALSE;
- QListIterator<GuardedNodes> li(m_ifGuardedNodes);
- GuardedNodes *nodes;
- for (li.toFirst();(nodes=li.current()) && !processed;++li)
+ for (auto &nodes : m_ifGuardedNodes)
{
if (nodes->guardAst)
{
@@ -2938,6 +3051,7 @@ class TemplateNodeIf : public TemplateNodeCreator<TemplateNodeIf>
{
nodes->trueNodes.render(ts,c);
processed=TRUE;
+ break;
}
}
else
@@ -2960,7 +3074,7 @@ class TemplateNodeIf : public TemplateNodeCreator<TemplateNodeIf>
ExprAst *guardAst = 0;
TemplateNodeList trueNodes;
};
- QList<GuardedNodes> m_ifGuardedNodes;
+ std::vector< std::unique_ptr<GuardedNodes> > m_ifGuardedNodes;
TemplateNodeList m_falseNodes;
};
@@ -2972,26 +3086,25 @@ class TemplateNodeRepeat : public TemplateNodeCreator<TemplateNodeRepeat>
TemplateNodeRepeat(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeRepeat>(parser,parent,line)
{
- TRACE(("{TemplateNodeRepeat(%s)\n",data.data()));
+ TRACE(("{TemplateNodeRepeat(%s)\n",qPrint(data)));
ExpressionParser expParser(parser,line);
m_expr = expParser.parse(data);
- QStrList stopAt;
- stopAt.append("endrepeat");
+ StringVector stopAt = { "endrepeat" };
parser->parse(this,line,stopAt,m_repeatNodes);
parser->removeNextToken(); // skip over endrepeat
- TRACE(("}TemplateNodeRepeat(%s)\n",data.data()));
+ TRACE(("}TemplateNodeRepeat(%s)\n",qPrint(data)));
}
~TemplateNodeRepeat()
{
delete m_expr;
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
ci->setLocation(m_templateName,m_line);
TemplateVariant v;
- if (m_expr && (v=m_expr->resolve(c)).type()==TemplateVariant::Integer)
+ if (m_expr && (v=m_expr->resolve(c)).isInt())
{
int i, n = v.toInt();
for (i=0;i<n;i++)
@@ -3027,7 +3140,7 @@ class TemplateNodeRange : public TemplateNodeCreator<TemplateNodeRange>
TemplateNodeRange(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeRange>(parser,parent,line), m_down(FALSE)
{
- TRACE(("{TemplateNodeRange(%s)\n",data.data()));
+ TRACE(("{TemplateNodeRange(%s)\n",qPrint(data)));
QCString start,end;
int i1 = data.find(" from ");
int i2 = data.find(" to ");
@@ -3085,11 +3198,10 @@ class TemplateNodeRange : public TemplateNodeCreator<TemplateNodeRange>
m_startExpr = expParser.parse(start);
m_endExpr = expParser.parse(end);
- QStrList stopAt;
- stopAt.append("endrange");
+ StringVector stopAt = { "endrange" };
parser->parse(this,line,stopAt,m_loopNodes);
parser->removeNextToken(); // skip over endrange
- TRACE(("}TemplateNodeRange(%s)\n",data.data()));
+ TRACE(("}TemplateNodeRange(%s)\n",qPrint(data)));
}
~TemplateNodeRange()
@@ -3098,7 +3210,7 @@ class TemplateNodeRange : public TemplateNodeCreator<TemplateNodeRange>
delete m_endExpr;
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -3109,7 +3221,7 @@ class TemplateNodeRange : public TemplateNodeCreator<TemplateNodeRange>
{
TemplateVariant vs = m_startExpr->resolve(c);
TemplateVariant ve = m_endExpr->resolve(c);
- if (vs.type()==TemplateVariant::Integer && ve.type()==TemplateVariant::Integer)
+ if (vs.isInt() && ve.isInt())
{
int s = vs.toInt();
int e = ve.toInt();
@@ -3161,11 +3273,11 @@ class TemplateNodeRange : public TemplateNodeCreator<TemplateNodeRange>
s,m_down?"downto":"to",e);
}
}
- else if (vs.type()!=TemplateVariant::Integer)
+ else if (!vs.isInt())
{
ci->warn(m_templateName,m_line,"range requires a start value of integer type!");
}
- else if (ve.type()!=TemplateVariant::Integer)
+ else if (!ve.isInt())
{
ci->warn(m_templateName,m_line,"range requires an end value of integer type!");
}
@@ -3197,7 +3309,7 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
TemplateNodeFor(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeFor>(parser,parent,line), m_reversed(FALSE)
{
- TRACE(("{TemplateNodeFor(%s)\n",data.data()));
+ TRACE(("{TemplateNodeFor(%s)\n",qPrint(data)));
QCString exprStr;
int i = data.find(" in ");
if (i==-1)
@@ -3239,19 +3351,16 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
ExpressionParser expParser(parser,line);
m_expr = expParser.parse(exprStr);
- QStrList stopAt;
- stopAt.append("endfor");
- stopAt.append("empty");
+ StringVector stopAt = { "endfor", "empty" };
parser->parse(this,line,stopAt,m_loopNodes);
- TemplateToken *tok = parser->takeNextToken();
+ auto tok = parser->takeNextToken();
if (tok && tok->data=="empty")
{
- stopAt.removeLast();
+ stopAt.pop_back();
parser->parse(this,line,stopAt,m_emptyNodes);
parser->removeNextToken(); // skip over endfor
}
- delete tok;
- TRACE(("}TemplateNodeFor(%s)\n",data.data()));
+ TRACE(("}TemplateNodeFor(%s)\n",qPrint(data)));
}
~TemplateNodeFor()
@@ -3259,7 +3368,7 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
delete m_expr;
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -3269,7 +3378,7 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
if (m_expr)
{
TemplateVariant v = m_expr->resolve(c);
- if (v.type()==TemplateVariant::Function)
+ if (v.isFunction())
{
v = v.call(std::vector<TemplateVariant>());
}
@@ -3310,7 +3419,7 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
{
c->set(m_vars[vi++],ve);
}
- else if (m_vars.size()>1 && ve.type()==TemplateVariant::Struct)
+ else if (m_vars.size()>1 && ve.isStruct())
// loop variables represent elements in a list item
{
for (uint i=0;i<m_vars.size();i++,vi++)
@@ -3333,7 +3442,7 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
}
else // simple type...
{
- ci->warn(m_templateName,m_line,"for requires a variable of list type, got type '%s'!",v.typeAsString().data());
+ ci->warn(m_templateName,m_line,"for requires a variable of list type, got type '%s'!",qPrint(v.typeAsString()));
}
}
}
@@ -3356,13 +3465,12 @@ class TemplateNodeMsg : public TemplateNodeCreator<TemplateNodeMsg>
: TemplateNodeCreator<TemplateNodeMsg>(parser,parent,line)
{
TRACE(("{TemplateNodeMsg()\n"));
- QStrList stopAt;
- stopAt.append("endmsg");
+ StringVector stopAt = { "endmsg" };
parser->parse(this,line,stopAt,m_nodes);
parser->removeNextToken(); // skip over endmsg
TRACE(("}TemplateNodeMsg()\n"));
}
- void render(FTextStream &, TemplateContext *c)
+ void render(TextStream &, TemplateContext *c)
{
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -3371,9 +3479,10 @@ class TemplateNodeMsg : public TemplateNodeCreator<TemplateNodeMsg>
ci->setActiveEscapeIntf(0); // avoid escaping things we send to standard out
bool enable = ci->spacelessEnabled();
ci->enableSpaceless(FALSE);
- FTextStream ts(stdout);
- m_nodes.render(ts,c);
- ts << endl;
+ TextStream t(&std::cout);
+ m_nodes.render(t,c);
+ t.flush();
+ std::cout << "\n";
ci->setActiveEscapeIntf(escIntf);
ci->enableSpaceless(enable);
}
@@ -3391,20 +3500,19 @@ class TemplateNodeBlock : public TemplateNodeCreator<TemplateNodeBlock>
TemplateNodeBlock(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeBlock>(parser,parent,line)
{
- TRACE(("{TemplateNodeBlock(%s)\n",data.data()));
+ TRACE(("{TemplateNodeBlock(%s)\n",qPrint(data)));
m_blockName = data;
if (m_blockName.isEmpty())
{
parser->warn(parser->templateName(),line,"block tag without name");
}
- QStrList stopAt;
- stopAt.append("endblock");
+ StringVector stopAt = { "endblock" };
parser->parse(this,line,stopAt,m_nodes);
parser->removeNextToken(); // skip over endblock
- TRACE(("}TemplateNodeBlock(%s)\n",data.data()));
+ TRACE(("}TemplateNodeBlock(%s)\n",qPrint(data)));
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -3417,8 +3525,7 @@ class TemplateNodeBlock : public TemplateNodeCreator<TemplateNodeBlock>
if (nb) // block is overruled
{
ci->push();
- QGString super;
- FTextStream ss(&super);
+ TextStream ss;
// get super block of block nb
TemplateNodeBlock *sb = ci->blockContext()->get(m_blockName);
if (sb && sb!=nb && sb!=this) // nb and sb both overrule this block
@@ -3429,6 +3536,7 @@ class TemplateNodeBlock : public TemplateNodeCreator<TemplateNodeBlock>
{
m_nodes.render(ss,c); // render parent of nb to string
}
+ QCString super = ss.str();
// add 'block.super' variable to allow access to parent block content
TemplateAutoRef<TemplateStruct> superBlock(TemplateStruct::alloc());
superBlock->set("super",TemplateVariant(super.data(),TRUE));
@@ -3469,23 +3577,23 @@ class TemplateNodeExtend : public TemplateNodeCreator<TemplateNodeExtend>
TemplateNodeExtend(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeExtend>(parser,parent,line)
{
- TRACE(("{TemplateNodeExtend(%s)\n",data.data()));
+ TRACE(("{TemplateNodeExtend(%s)\n",qPrint(data)));
ExpressionParser ep(parser,line);
if (data.isEmpty())
{
parser->warn(m_templateName,line,"extend tag is missing template file argument");
}
m_extendExpr = ep.parse(data);
- QStrList stopAt;
+ StringVector stopAt;
parser->parse(this,line,stopAt,m_nodes);
- TRACE(("}TemplateNodeExtend(%s)\n",data.data()));
+ TRACE(("}TemplateNodeExtend(%s)\n",qPrint(data)));
}
~TemplateNodeExtend()
{
delete m_extendExpr;
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -3510,16 +3618,14 @@ class TemplateNodeExtend : public TemplateNodeCreator<TemplateNodeExtend>
TemplateBlockContext *bc = ci->blockContext();
// add overruling blocks to the context
- QListIterator<TemplateNode> li(m_nodes);
- TemplateNode *n;
- for (li.toFirst();(n=li.current());++li)
+ for (const auto &n : m_nodes)
{
- TemplateNodeBlock *nb = dynamic_cast<TemplateNodeBlock*>(n);
+ TemplateNodeBlock *nb = dynamic_cast<TemplateNodeBlock*>(n.get());
if (nb)
{
bc->add(nb);
}
- TemplateNodeMsg *msg = dynamic_cast<TemplateNodeMsg*>(n);
+ TemplateNodeMsg *msg = dynamic_cast<TemplateNodeMsg*>(n.get());
if (msg)
{
msg->render(ts,c);
@@ -3535,7 +3641,7 @@ class TemplateNodeExtend : public TemplateNodeCreator<TemplateNodeExtend>
}
else
{
- ci->warn(m_templateName,m_line,"failed to load template %s for extend",extendFile.data());
+ ci->warn(m_templateName,m_line,"failed to load template %s for extend",qPrint(extendFile));
}
}
}
@@ -3552,7 +3658,7 @@ class TemplateNodeInclude : public TemplateNodeCreator<TemplateNodeInclude>
TemplateNodeInclude(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeInclude>(parser,parent,line)
{
- TRACE(("TemplateNodeInclude(%s)\n",data.data()));
+ TRACE(("TemplateNodeInclude(%s)\n",qPrint(data)));
ExpressionParser ep(parser,line);
if (data.isEmpty())
{
@@ -3564,7 +3670,7 @@ class TemplateNodeInclude : public TemplateNodeCreator<TemplateNodeInclude>
{
delete m_includeExpr;
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -3590,7 +3696,7 @@ class TemplateNodeInclude : public TemplateNodeCreator<TemplateNodeInclude>
}
else
{
- ci->warn(m_templateName,m_line,"failed to load template '%s' for include",includeFile.data()?includeFile.data():"");
+ ci->warn(m_templateName,m_line,"failed to load template '%s' for include",qPrint(includeFile));
}
}
}
@@ -3603,22 +3709,18 @@ class TemplateNodeInclude : public TemplateNodeCreator<TemplateNodeInclude>
//----------------------------------------------------------
-static void stripLeadingWhiteSpace(QGString &s)
+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.data();
- 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';
+ 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 */
@@ -3628,7 +3730,7 @@ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate>
TemplateNodeCreate(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeCreate>(parser,parent,line), m_templateExpr(0), m_fileExpr(0)
{
- TRACE(("TemplateNodeCreate(%s)\n",data.data()));
+ TRACE(("TemplateNodeCreate(%s)\n",qPrint(data)));
if (data.isEmpty())
{
parser->warn(m_templateName,line,"create tag is missing arguments");
@@ -3661,7 +3763,7 @@ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate>
delete m_templateExpr;
delete m_fileExpr;
}
- void render(FTextStream &, TemplateContext *c)
+ void render(TextStream &, TemplateContext *c)
{
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -3694,21 +3796,21 @@ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate>
TemplateImpl *createTemplate = ct ? dynamic_cast<TemplateImpl*>(ct) : 0;
if (createTemplate)
{
- mkpath(ci,outputFile);
+ mkpath(ci,outputFile.str());
if (!ci->outputDirectory().isEmpty())
{
outputFile.prepend(ci->outputDirectory()+"/");
}
- //printf("NoteCreate(%s)\n",outputFile.data());
- QFile f(outputFile);
- if (f.open(IO_WriteOnly))
+ //printf("NoteCreate(%s)\n",qPrint(outputFile));
+ std::ofstream f(outputFile.str(),std::ofstream::out | std::ofstream::binary);
+ if (f.is_open())
{
+ TextStream ts(&f);
TemplateEscapeIntf *escIntf = ci->escapeIntf();
ci->selectEscapeIntf(extension);
- FTextStream ts(&f);
- QGString out;
- FTextStream os(&out);
+ TextStream os;
createTemplate->render(os,c);
+ QCString out = os.str();
stripLeadingWhiteSpace(out);
ts << out;
t->engine()->unload(t);
@@ -3716,12 +3818,12 @@ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate>
}
else
{
- ci->warn(m_templateName,m_line,"failed to open output file '%s' for create command",outputFile.data());
+ ci->warn(m_templateName,m_line,"failed to open output file '%s' for create command",qPrint(outputFile));
}
}
else
{
- ci->warn(m_templateName,m_line,"failed to load template '%s' for include",templateFile.data());
+ ci->warn(m_templateName,m_line,"failed to load template '%s' for include",qPrint(templateFile));
}
t->engine()->setOutputExtension("");
}
@@ -3751,18 +3853,17 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree>
TemplateNodeTree(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeTree>(parser,parent,line)
{
- TRACE(("{TemplateNodeTree(%s)\n",data.data()));
+ TRACE(("{TemplateNodeTree(%s)\n",qPrint(data)));
ExpressionParser ep(parser,line);
if (data.isEmpty())
{
parser->warn(m_templateName,line,"recursetree tag is missing data argument");
}
m_treeExpr = ep.parse(data);
- QStrList stopAt;
- stopAt.append("endrecursetree");
+ StringVector stopAt = { "endrecursetree" };
parser->parse(this,line,stopAt,m_treeNodes);
parser->removeNextToken(); // skip over endrecursetree
- TRACE(("}TemplateNodeTree(%s)\n",data.data()));
+ TRACE(("}TemplateNodeTree(%s)\n",qPrint(data)));
}
~TemplateNodeTree()
{
@@ -3780,8 +3881,7 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree>
TemplateContext *c = ctx->templateCtx;
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return QCString(); // should not happen
- QGString result;
- FTextStream ss(&result);
+ TextStream ss;
c->push();
TemplateVariant node;
TemplateListIntf::ConstIterator *it = ctx->list->createIterator();
@@ -3799,7 +3899,7 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree>
if (list && list->count()>0) // non-empty list
{
TreeContext childCtx(this,list,ctx->templateCtx);
- TemplateVariant children(TemplateVariant::Delegate::fromFunction(&childCtx,renderChildrenStub));
+ TemplateVariant children(TemplateVariant::FunctionDelegate::fromFunction(&childCtx,renderChildrenStub));
children.setRaw(TRUE);
c->set("children",children);
m_treeNodes.render(ss,c);
@@ -3807,7 +3907,7 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree>
}
else if (list==0)
{
- ci->warn(m_templateName,m_line,"recursetree: children attribute has type '%s' instead of list\n",v.typeAsString().data());
+ ci->warn(m_templateName,m_line,"recursetree: children attribute has type '%s' instead of list\n",qPrint(v.typeAsString()));
}
}
//else
@@ -3823,9 +3923,9 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree>
}
c->pop();
delete it;
- return result.data();
+ return ss.str();
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
//printf("TemplateNodeTree::render()\n");
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
@@ -3856,17 +3956,15 @@ class TemplateNodeIndexEntry : public TemplateNodeCreator<TemplateNodeIndexEntry
{
struct Mapping
{
- Mapping(const QCString &n,ExprAst *e) : name(n), value(e) {}
- ~Mapping() { delete value; }
+ Mapping(const QCString &n,std::unique_ptr<ExprAst> &&e) : name(n), value(std::move(e)) {}
QCString name;
- ExprAst *value = 0;
+ std::unique_ptr<ExprAst> value = 0;
};
public:
TemplateNodeIndexEntry(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeIndexEntry>(parser,parent,line)
{
- TRACE(("{TemplateNodeIndexEntry(%s)\n",data.data()));
- m_args.setAutoDelete(TRUE);
+ TRACE(("{TemplateNodeIndexEntry(%s)\n",qPrint(data)));
ExpressionParser expParser(parser,line);
std::vector<QCString> args = split(data," ");
auto it = args.begin();
@@ -3887,38 +3985,36 @@ class TemplateNodeIndexEntry : public TemplateNodeCreator<TemplateNodeIndexEntry
ExprAst *expr = expParser.parse(arg.mid(j+1));
if (expr)
{
- m_args.append(new Mapping(arg.left(j),expr));
+ m_args.emplace_back(arg.left(j),std::unique_ptr<ExprAst>(expr));
}
}
else
{
- parser->warn(parser->templateName(),line,"invalid argument '%s' for indexentry tag",arg.data());
+ parser->warn(parser->templateName(),line,"invalid argument '%s' for indexentry tag",qPrint(arg));
}
++it;
}
}
- TRACE(("}TemplateNodeIndexEntry(%s)\n",data.data()));
+ TRACE(("}TemplateNodeIndexEntry(%s)\n",qPrint(data)));
}
- void render(FTextStream &, TemplateContext *c)
+ void render(TextStream &, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
if (!m_name.isEmpty())
{
ci->setLocation(m_templateName,m_line);
- QListIterator<Mapping> it(m_args);
- Mapping *mapping;
std::vector<TemplateKeyValue> list;
- for (it.toFirst();(mapping=it.current());++it)
+ for (const auto &mapping : m_args)
{
- list.push_back(TemplateKeyValue(mapping->name,mapping->value->resolve(c)));
+ list.emplace_back(mapping.name,mapping.value->resolve(c));
}
ci->addIndexEntry(m_name,list);
}
}
private:
QCString m_name;
- QList<Mapping> m_args;
+ std::vector<Mapping> m_args;
};
//----------------------------------------------------------
@@ -3930,7 +4026,7 @@ class TemplateNodeOpenSubIndex : public TemplateNodeCreator<TemplateNodeOpenSubI
TemplateNodeOpenSubIndex(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeOpenSubIndex>(parser,parent,line)
{
- TRACE(("{TemplateNodeOpenSubIndex(%s)\n",data.data()));
+ TRACE(("{TemplateNodeOpenSubIndex(%s)\n",qPrint(data)));
m_name = data.stripWhiteSpace();
if (m_name.isEmpty())
{
@@ -3938,12 +4034,12 @@ class TemplateNodeOpenSubIndex : public TemplateNodeCreator<TemplateNodeOpenSubI
}
else if (m_name.find(' ')!=-1)
{
- parser->warn(parser->templateName(),line,"Expected single argument for opensubindex tag got '%s'",data.data());
+ parser->warn(parser->templateName(),line,"Expected single argument for opensubindex tag got '%s'",qPrint(data));
m_name="";
}
- TRACE(("}TemplateNodeOpenSubIndex(%s)\n",data.data()));
+ TRACE(("}TemplateNodeOpenSubIndex(%s)\n",qPrint(data)));
}
- void render(FTextStream &, TemplateContext *c)
+ void render(TextStream &, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -3966,7 +4062,7 @@ class TemplateNodeCloseSubIndex : public TemplateNodeCreator<TemplateNodeCloseSu
TemplateNodeCloseSubIndex(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeCloseSubIndex>(parser,parent,line)
{
- TRACE(("{TemplateNodeCloseSubIndex(%s)\n",data.data()));
+ TRACE(("{TemplateNodeCloseSubIndex(%s)\n",qPrint(data)));
m_name = data.stripWhiteSpace();
if (m_name.isEmpty())
{
@@ -3974,12 +4070,12 @@ class TemplateNodeCloseSubIndex : public TemplateNodeCreator<TemplateNodeCloseSu
}
else if (m_name.find(' ')!=-1 || m_name.isEmpty())
{
- parser->warn(parser->templateName(),line,"Expected single argument for closesubindex tag got '%s'",data.data());
+ parser->warn(parser->templateName(),line,"Expected single argument for closesubindex tag got '%s'",qPrint(data));
m_name="";
}
- TRACE(("}TemplateNodeCloseSubIndex(%s)\n",data.data()));
+ TRACE(("}TemplateNodeCloseSubIndex(%s)\n",qPrint(data)));
}
- void render(FTextStream &, TemplateContext *c)
+ void render(TextStream &, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -4001,19 +4097,18 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith>
{
struct Mapping
{
- Mapping(const QCString &n,ExprAst *e) : name(n), value(e) {}
- ~Mapping() { delete value; }
+ Mapping(const QCString &n,std::unique_ptr<ExprAst> &&e) : name(n), value(std::move(e)) {}
QCString name;
- ExprAst *value;
+ std::unique_ptr<ExprAst> value;
};
public:
TemplateNodeWith(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeWith>(parser,parent,line)
{
- TRACE(("{TemplateNodeWith(%s)\n",data.data()));
- m_args.setAutoDelete(TRUE);
+ 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())
@@ -4025,43 +4120,40 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith>
ExprAst *expr = expParser.parse(arg.mid(j+1));
if (expr)
{
- m_args.append(new Mapping(arg.left(j),expr));
+ m_args.emplace_back(arg.left(j),std::unique_ptr<ExprAst>(expr));
}
}
else
{
- parser->warn(parser->templateName(),line,"invalid argument '%s' for 'with' tag",arg.data());
+ parser->warn(parser->templateName(),line,"invalid argument '%s' for 'with' tag",qPrint(arg));
}
++it;
}
- QStrList stopAt;
- stopAt.append("endwith");
+ StringVector stopAt = { "endwith" };
parser->parse(this,line,stopAt,m_nodes);
parser->removeNextToken(); // skip over endwith
- TRACE(("}TemplateNodeWith(%s)\n",data.data()));
+ TRACE(("}TemplateNodeWith(%s)\n",qPrint(data)));
}
~TemplateNodeWith()
{
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
ci->setLocation(m_templateName,m_line);
c->push();
- QListIterator<Mapping> it(m_args);
- Mapping *mapping;
- for (it.toFirst();(mapping=it.current());++it)
+ for (const auto &mapping : m_args)
{
- TemplateVariant value = mapping->value->resolve(c);
- ci->set(mapping->name,value);
+ TemplateVariant value = mapping.value->resolve(c);
+ ci->set(mapping.name,value);
}
m_nodes.render(ts,c);
c->pop();
}
private:
TemplateNodeList m_nodes;
- QList<Mapping> m_args;
+ std::vector<Mapping> m_args;
};
//----------------------------------------------------------
@@ -4073,8 +4165,7 @@ class TemplateNodeCycle : public TemplateNodeCreator<TemplateNodeCycle>
TemplateNodeCycle(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeCycle>(parser,parent,line)
{
- TRACE(("{TemplateNodeCycle(%s)\n",data.data()));
- m_args.setAutoDelete(TRUE);
+ TRACE(("{TemplateNodeCycle(%s)\n",qPrint(data)));
m_index=0;
ExpressionParser expParser(parser,line);
std::vector<QCString> args = split(data," ");
@@ -4084,24 +4175,25 @@ class TemplateNodeCycle : public TemplateNodeCreator<TemplateNodeCycle>
ExprAst *expr = expParser.parse(*it);
if (expr)
{
- m_args.append(expr);
+ m_args.push_back(std::unique_ptr<ExprAst>(expr));
}
++it;
}
- if (m_args.count()<2)
+ if (m_args.size()<2)
{
- parser->warn(parser->templateName(),line,"expected at least two arguments for cycle command, got %d",m_args.count());
+ parser->warn(parser->templateName(),line,"expected at least two arguments for cycle command, got %zu",m_args.size());
}
- TRACE(("}TemplateNodeCycle(%s)\n",data.data()));
+ TRACE(("}TemplateNodeCycle(%s)\n",qPrint(data)));
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ if (ci==0) return; // should not happen
ci->setLocation(m_templateName,m_line);
- if (m_index<m_args.count())
+ if (m_index<m_args.size())
{
- TemplateVariant v = m_args.at(m_index)->resolve(c);
- if (v.type()==TemplateVariant::Function)
+ TemplateVariant v = m_args[m_index]->resolve(c);
+ if (v.isFunction())
{
v = v.call(std::vector<TemplateVariant>());
}
@@ -4128,14 +4220,14 @@ class TemplateNodeCycle : public TemplateNodeCreator<TemplateNodeCycle>
}
}
}
- if (++m_index==m_args.count()) // wrap around
+ if (++m_index==m_args.size()) // wrap around
{
m_index=0;
}
}
private:
- uint m_index = 0;
- QList<ExprAst> m_args;
+ size_t m_index = 0;
+ ExprAstList m_args;
};
//----------------------------------------------------------
@@ -4152,24 +4244,23 @@ class TemplateNodeSet : public TemplateNodeCreator<TemplateNodeSet>
};
public:
TemplateNodeSet(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
- : TemplateNodeCreator<TemplateNodeSet>(parser,parent,line), m_mapping(0)
+ : TemplateNodeCreator<TemplateNodeSet>(parser,parent,line)
{
- TRACE(("{TemplateNodeSet(%s)\n",data.data()));
+ TRACE(("{TemplateNodeSet(%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 = new Mapping(data.left(j),expr);
+ m_mapping = std::make_unique<Mapping>(data.left(j),expr);
}
- TRACE(("}TemplateNodeSet(%s)\n",data.data()));
+ TRACE(("}TemplateNodeSet(%s)\n",qPrint(data)));
}
~TemplateNodeSet()
{
- delete m_mapping;
}
- void render(FTextStream &, TemplateContext *c)
+ void render(TextStream &, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -4181,7 +4272,7 @@ class TemplateNodeSet : public TemplateNodeCreator<TemplateNodeSet>
}
}
private:
- Mapping *m_mapping = 0;
+ std::unique_ptr<Mapping> m_mapping;
};
//----------------------------------------------------------
@@ -4194,13 +4285,12 @@ class TemplateNodeSpaceless : public TemplateNodeCreator<TemplateNodeSpaceless>
: TemplateNodeCreator<TemplateNodeSpaceless>(parser,parent,line)
{
TRACE(("{TemplateNodeSpaceless()\n"));
- QStrList stopAt;
- stopAt.append("endspaceless");
+ StringVector stopAt = { "endspaceless" };
parser->parse(this,line,stopAt,m_nodes);
parser->removeNextToken(); // skip over endwith
TRACE(("}TemplateNodeSpaceless()\n"));
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -4223,7 +4313,7 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers>
TemplateNodeMarkers(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeMarkers>(parser,parent,line), m_listExpr(0), m_patternExpr(0)
{
- TRACE(("{TemplateNodeMarkers(%s)\n",data.data()));
+ TRACE(("{TemplateNodeMarkers(%s)\n",qPrint(data)));
int i = data.find(" in ");
int w = data.find(" with ");
if (i==-1 || w==-1 || w<i)
@@ -4237,18 +4327,17 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers>
m_listExpr = expParser.parse(data.mid(i+4,w-i-4));
m_patternExpr = expParser.parse(data.right(data.length()-w-6));
}
- QStrList stopAt;
- stopAt.append("endmarkers");
+ StringVector stopAt = { "endmarkers" };
parser->parse(this,line,stopAt,m_nodes);
parser->removeNextToken(); // skip over endmarkers
- TRACE(("}TemplateNodeMarkers(%s)\n",data.data()));
+ TRACE(("}TemplateNodeMarkers(%s)\n",qPrint(data)));
}
~TemplateNodeMarkers()
{
delete m_listExpr;
delete m_patternExpr;
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -4260,30 +4349,36 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers>
TemplateVariant patternStr = m_patternExpr->resolve(c);
if (list)
{
- if (patternStr.type()==TemplateVariant::String)
+ if (patternStr.isString())
{
TemplateListIntf::ConstIterator *it = list->createIterator();
c->push();
- QCString str = patternStr.toString();
- QRegExp marker("@[0-9]+"); // pattern for a marker, i.e. @0, @1 ... @12, etc
- int index=0,newIndex,matchLen;
- while ((newIndex=marker.match(str,index,&matchLen))!=-1)
+ std::string str = patternStr.toString().str();
+
+ static const reg::Ex marker(R"(@\d+)");
+ reg::Iterator re_it(str,marker);
+ reg::Iterator end;
+ size_t index=0;
+ for ( ; re_it!=end ; ++re_it)
{
+ const auto &match = *re_it;
+ size_t newIndex = match.position();
+ size_t matchLen = match.length();
+ std::string part = str.substr(index,newIndex-index);
if (ci->needsRecoding())
{
- ts << ci->recode(str.mid(index,newIndex-index)); // write text before marker
+ ts << ci->recode(QCString(part)); // write text before marker
}
else
{
- ts << str.mid(index,newIndex-index); // write text before marker
+ ts << part; // write text before marker
}
- bool ok;
- uint entryIndex = str.mid(newIndex+1,matchLen-1).toUInt(&ok); // get marker id
+ unsigned long entryIndex = std::stoul(match.str().substr(1));
TemplateVariant var;
- uint i=0;
+ size_t i=0;
// search for list element at position id
for (it->toFirst(); (it->current(var)) && i<entryIndex; it->toNext(),i++) {}
- if (ok && i==entryIndex) // found element
+ if (i==entryIndex) // found element
{
TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc());
s->set("id",(int)i);
@@ -4294,10 +4389,6 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers>
m_nodes.render(ts,c);
ci->enableSpaceless(wasSpaceless);
}
- else if (!ok)
- {
- ci->warn(m_templateName,m_line,"markers pattern string has invalid markers '%s'",str.data());
- }
else if (i<entryIndex)
{
ci->warn(m_templateName,m_line,"markers list does not an element for marker position %d",i);
@@ -4306,11 +4397,11 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers>
}
if (ci->needsRecoding())
{
- ts << ci->recode(str.right(str.length()-index)); // write text after last marker
+ ts << ci->recode(str.substr(index)); // write text after last marker
}
else
{
- ts << str.right(str.length()-index); // write text after last marker
+ ts << str.substr(index); // write text after last marker
}
c->pop();
delete it;
@@ -4343,13 +4434,12 @@ class TemplateNodeTabbing : public TemplateNodeCreator<TemplateNodeTabbing>
: TemplateNodeCreator<TemplateNodeTabbing>(parser,parent,line)
{
TRACE(("{TemplateNodeTabbing()\n"));
- QStrList stopAt;
- stopAt.append("endtabbing");
+ StringVector stopAt = { "endtabbing" };
parser->parse(this,line,stopAt,m_nodes);
parser->removeNextToken(); // skip over endtabbing
TRACE(("}TemplateNodeTabbing()\n"));
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -4372,7 +4462,7 @@ class TemplateNodeResource : public TemplateNodeCreator<TemplateNodeResource>
TemplateNodeResource(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeResource>(parser,parent,line)
{
- TRACE(("{TemplateNodeResource(%s)\n",data.data()));
+ TRACE(("{TemplateNodeResource(%s)\n",qPrint(data)));
ExpressionParser ep(parser,line);
int i;
if (data.isEmpty())
@@ -4386,19 +4476,25 @@ 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);
m_asExpr = 0;
}
- TRACE(("}TemplateNodeResource(%s)\n",data.data()));
+ TRACE(("}TemplateNodeResource(%s)\n",qPrint(data)));
}
~TemplateNodeResource()
{
delete m_resExpr;
delete m_asExpr;
}
- void render(FTextStream &, TemplateContext *c)
+ void render(TextStream &, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -4416,13 +4512,14 @@ class TemplateNodeResource : public TemplateNodeCreator<TemplateNodeResource>
if (m_asExpr)
{
QCString targetFile = m_asExpr->resolve(c).toString();
- mkpath(ci,targetFile);
+ 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
@@ -4435,6 +4532,7 @@ class TemplateNodeResource : public TemplateNodeCreator<TemplateNodeResource>
private:
ExprAst *m_resExpr = 0;
ExprAst *m_asExpr = 0;
+ bool m_append = false;
};
//----------------------------------------------------------
@@ -4446,7 +4544,7 @@ class TemplateNodeEncoding : public TemplateNodeCreator<TemplateNodeEncoding>
TemplateNodeEncoding(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeEncoding>(parser,parent,line)
{
- TRACE(("{TemplateNodeEncoding(%s)\n",data.data()));
+ TRACE(("{TemplateNodeEncoding(%s)\n",qPrint(data)));
ExpressionParser ep(parser,line);
if (data.isEmpty())
{
@@ -4457,17 +4555,16 @@ class TemplateNodeEncoding : public TemplateNodeCreator<TemplateNodeEncoding>
{
m_encExpr = ep.parse(data);
}
- QStrList stopAt;
- stopAt.append("endencoding");
+ StringVector stopAt = { "endencoding" };
parser->parse(this,line,stopAt,m_nodes);
parser->removeNextToken(); // skip over endencoding
- TRACE(("}TemplateNodeEncoding(%s)\n",data.data()));
+ TRACE(("}TemplateNodeEncoding(%s)\n",qPrint(data)));
}
~TemplateNodeEncoding()
{
delete m_encExpr;
}
- void render(FTextStream &ts, TemplateContext *c)
+ void render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
@@ -4514,13 +4611,14 @@ class TemplateNodeFactory
int line,
const QCString &data)
{
- if (m_registry.find(name)==0) return 0;
- return ((CreateFunc)m_registry[name])(parser,parent,line,data);
+ auto it = m_registry.find(name.str());
+ if (it==m_registry.end()) return 0;
+ return it->second(parser,parent,line,data);
}
void registerTemplateNode(const QCString &name,CreateFunc func)
{
- m_registry.insert(name,(void*)func);
+ m_registry.insert(std::make_pair(name.str(),func));
}
/** @brief Helper class for registering a template AST node */
@@ -4534,7 +4632,7 @@ class TemplateNodeFactory
};
private:
- QDict<void> m_registry;
+ std::unordered_map<std::string,CreateFunc> m_registry;
};
// register a handler for each start tag we support
@@ -4562,57 +4660,53 @@ static TemplateNodeFactory::AutoRegister<TemplateNodeCloseSubIndex> autoRefClose
//----------------------------------------------------------
-TemplateBlockContext::TemplateBlockContext() : m_blocks(257)
+TemplateBlockContext::TemplateBlockContext()
{
- m_blocks.setAutoDelete(TRUE);
}
TemplateNodeBlock *TemplateBlockContext::get(const QCString &name) const
{
- QList<TemplateNodeBlock> *list = m_blocks.find(name);
- if (list==0 || list->count()==0)
+ auto it = m_blocks.find(name.str());
+ if (it==m_blocks.end() || it->second.empty())
{
return 0;
}
else
{
- return list->getLast();
+ return it->second.back();
}
}
-TemplateNodeBlock *TemplateBlockContext::pop(const QCString &name) const
+TemplateNodeBlock *TemplateBlockContext::pop(const QCString &name)
{
- QList<TemplateNodeBlock> *list = m_blocks.find(name);
- if (list==0 || list->count()==0)
+ auto it = m_blocks.find(name.str());
+ if (it==m_blocks.end() || it->second.empty())
{
return 0;
}
else
{
- return list->take(list->count()-1);
+ TemplateNodeBlock *bld = it->second.back();
+ it->second.pop_back();
+ return bld;
}
}
void TemplateBlockContext::add(TemplateNodeBlock *block)
{
- QList<TemplateNodeBlock> *list = m_blocks.find(block->name());
- if (list==0)
+ auto it = m_blocks.find(block->name().str());
+ if (it==m_blocks.end())
{
- list = new QList<TemplateNodeBlock>;
- m_blocks.insert(block->name(),list);
+ it = m_blocks.insert(std::make_pair(block->name().str(),NodeBlockList())).first;
}
- list->prepend(block);
+ it->second.push_front(block);
}
void TemplateBlockContext::add(TemplateBlockContext *ctx)
{
- QDictIterator< QList<TemplateNodeBlock> > di(ctx->m_blocks);
- QList<TemplateNodeBlock> *list;
- for (di.toFirst();(list=di.current());++di)
+ for (auto &kv : ctx->m_blocks)
{
- QListIterator<TemplateNodeBlock> li(*list);
- TemplateNodeBlock *nb;
- for (li.toFirst();(nb=li.current());++li)
+ for (auto &nb : kv.second)
{
add(nb);
}
@@ -4626,13 +4720,12 @@ void TemplateBlockContext::clear()
void TemplateBlockContext::push(TemplateNodeBlock *block)
{
- QList<TemplateNodeBlock> *list = m_blocks.find(block->name());
- if (list==0)
+ auto it = m_blocks.find(block->name().str());
+ if (it==m_blocks.end())
{
- list = new QList<TemplateNodeBlock>;
- m_blocks.insert(block->name(),list);
+ it = m_blocks.insert(std::make_pair(block->name().str(),NodeBlockList())).first;
}
- list->append(block);
+ it->second.push_back(block);
}
@@ -4643,12 +4736,12 @@ class TemplateLexer
{
public:
TemplateLexer(const TemplateEngine *engine,const QCString &fileName,const QCString &data);
- void tokenize(QList<TemplateToken> &tokens);
+ void tokenize(TemplateTokenStream &tokens);
void setOpenCloseCharacters(char openChar,char closeChar)
{ m_openChar=openChar; m_closeChar=closeChar; }
private:
- void addToken(QList<TemplateToken> &tokens,
- const char *data,int line,int startPos,int endPos,
+ void addToken(TemplateTokenStream &tokens,
+ const QCString &data,int line,int startPos,int endPos,
TemplateToken::Type type);
void reset();
const TemplateEngine *m_engine = 0;
@@ -4665,7 +4758,7 @@ TemplateLexer::TemplateLexer(const TemplateEngine *engine,const QCString &fileNa
m_closeChar='}';
}
-void TemplateLexer::tokenize(QList<TemplateToken> &tokens)
+void TemplateLexer::tokenize(TemplateTokenStream &tokens)
{
enum LexerStates
{
@@ -4680,8 +4773,8 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens)
StateEndVariable
};
+ if (m_data.isEmpty()) return;
const char *p=m_data.data();
- if (p==0) return;
int state=StateText;
int pos=0;
int lastTokenPos=0;
@@ -4748,10 +4841,10 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens)
{
// found tag!
state=StateText;
- addToken(tokens,m_data.data(),line,lastTokenPos,
+ addToken(tokens,m_data,line,lastTokenPos,
emptyOutputLine ? startLinePos : markStartPos,
TemplateToken::Text);
- addToken(tokens,m_data.data(),line,markStartPos+2,
+ addToken(tokens,m_data,line,markStartPos+2,
pos-1,TemplateToken::Block);
lastTokenPos = pos+1;
}
@@ -4781,7 +4874,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens)
{
// found comment tag!
state=StateText;
- addToken(tokens,m_data.data(),line,lastTokenPos,
+ addToken(tokens,m_data,line,lastTokenPos,
emptyOutputLine ? startLinePos : markStartPos,
TemplateToken::Text);
lastTokenPos = pos+1;
@@ -4829,10 +4922,10 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens)
{
// found variable tag!
state=StateText;
- addToken(tokens,m_data.data(),line,lastTokenPos,
+ addToken(tokens,m_data,line,lastTokenPos,
emptyOutputLine ? startLinePos : markStartPos,
TemplateToken::Text);
- addToken(tokens,m_data.data(),line,markStartPos+2,
+ addToken(tokens,m_data,line,markStartPos+2,
pos-1,TemplateToken::Variable);
lastTokenPos = pos+1;
}
@@ -4862,24 +4955,23 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens)
}
if (lastTokenPos<pos)
{
- addToken(tokens,m_data.data(),line,
+ addToken(tokens,m_data,line,
lastTokenPos,pos,
TemplateToken::Text);
}
}
-void TemplateLexer::addToken(QList<TemplateToken> &tokens,
- const char *data,int line,
+void TemplateLexer::addToken(TemplateTokenStream &tokens,
+ const QCString &data,int line,
int startPos,int endPos,
TemplateToken::Type type)
{
if (startPos<endPos)
{
- int len = endPos-startPos+1;
- QCString text(len);
- qstrncpy(text.rawData(),data+startPos,len);
+ int len = endPos-startPos;
+ QCString text = data.mid(startPos,len);
if (type!=TemplateToken::Text) text = text.stripWhiteSpace();
- tokens.append(new TemplateToken(type,text,line));
+ tokens.push_back(std::make_unique<TemplateToken>(type,text,line));
}
}
@@ -4887,29 +4979,29 @@ void TemplateLexer::addToken(QList<TemplateToken> &tokens,
TemplateParser::TemplateParser(const TemplateEngine *engine,
const QCString &templateName,
- QList<TemplateToken> &tokens) :
+ TemplateTokenStream &tokens) :
m_engine(engine), m_templateName(templateName), m_tokens(tokens)
{
}
void TemplateParser::parse(
- TemplateNode *parent,int line,const QStrList &stopAt,
- QList<TemplateNode> &nodes)
+ TemplateNode *parent,int line,const StringVector &stopAt,
+ TemplateNodeList &nodes)
{
TRACE(("{TemplateParser::parse\n"));
// process the tokens. Build node list
while (hasNextToken())
{
- TemplateToken *tok = takeNextToken();
- //printf("%p:Token type=%d data='%s' line=%d\n",
- // parent,tok->type,tok->data.data(),tok->line);
+ auto tok = takeNextToken();
+ 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:
- nodes.append(new TemplateNodeText(this,parent,tok->line,tok->data));
+ nodes.push_back(std::make_unique<TemplateNodeText>(this,parent,tok->line,tok->data));
break;
case TemplateToken::Variable: // {{ var }}
- nodes.append(new TemplateNodeVariable(this,parent,tok->line,tok->data));
+ nodes.push_back(std::make_unique<TemplateNodeVariable>(this,parent,tok->line,tok->data));
break;
case TemplateToken::Block: // {% tag %}
{
@@ -4919,22 +5011,23 @@ void TemplateParser::parse(
{
command=command.left(sep);
}
- if (stopAt.contains(command))
+ TemplateToken *tok_ptr = tok.get();
+ if (std::find(stopAt.begin(),stopAt.end(),command.str())!=stopAt.end())
{
- prependToken(tok);
+ prependToken(std::move(tok));
TRACE(("}TemplateParser::parse: stop\n"));
return;
}
QCString arg;
if (sep!=-1)
{
- arg = tok->data.mid(sep+1);
+ arg = tok_ptr->data.mid(sep+1);
}
- TemplateNode *node = TemplateNodeFactory::instance()->
- create(command,this,parent,tok->line,arg);
+ std::unique_ptr<TemplateNode> node { TemplateNodeFactory::instance()->
+ create(command,this,parent,tok_ptr->line,arg) };
if (node)
{
- nodes.append(node);
+ nodes.push_back(std::move(node));
}
else if (command=="empty" || command=="else" ||
command=="endif" || command=="endfor" ||
@@ -4945,59 +5038,59 @@ void TemplateParser::parse(
command=="endrange" || command=="endtabbing" ||
command=="endencoding")
{
- warn(m_templateName,tok->line,"Found tag '%s' without matching start tag",command.data());
+ warn(m_templateName,tok_ptr->line,"Found tag '%s' without matching start tag",qPrint(command));
}
else
{
- warn(m_templateName,tok->line,"Unknown tag '%s'",command.data());
+ warn(m_templateName,tok_ptr->line,"Unknown tag '%s'",qPrint(command));
}
}
break;
}
- delete tok;
}
- if (!stopAt.isEmpty())
+ if (!stopAt.empty())
{
- QStrListIterator it(stopAt);
- const char *s;
QCString options;
- for (it.toFirst();(s=it.current());++it)
+ for (const auto &s : stopAt)
{
if (!options.isEmpty()) options+=", ";
- options+=s;
+ options+=s.c_str();
}
warn(m_templateName,line,"Unclosed tag in template, expected one of: %s",
- options.data());
+ qPrint(options));
}
TRACE(("}TemplateParser::parse: last token\n"));
}
bool TemplateParser::hasNextToken() const
{
- return !m_tokens.isEmpty();
+ return !m_tokens.empty();
}
-TemplateToken *TemplateParser::takeNextToken()
+TemplateTokenPtr TemplateParser::takeNextToken()
{
- return m_tokens.take(0);
+ if (m_tokens.empty()) return TemplateTokenPtr();
+ auto tok = std::move(m_tokens.front());
+ m_tokens.pop_front();
+ return tok;
}
const TemplateToken *TemplateParser::currentToken() const
{
- return m_tokens.getFirst();
+ return m_tokens.front().get();
}
void TemplateParser::removeNextToken()
{
- m_tokens.removeFirst();
+ m_tokens.pop_front();
}
-void TemplateParser::prependToken(const TemplateToken *token)
+void TemplateParser::prependToken(TemplateTokenPtr &&token)
{
- m_tokens.prepend(token);
+ m_tokens.push_front(std::move(token));
}
-void TemplateParser::warn(const char *fileName,int line,const char *fmt,...) const
+void TemplateParser::warn(const QCString &fileName,int line,const char *fmt,...) const
{
va_list args;
va_start(args,fmt);
@@ -5022,33 +5115,30 @@ TemplateImpl::TemplateImpl(TemplateEngine *engine,const QCString &name,const QCS
{
lexer.setOpenCloseCharacters('<','>');
}
- QList<TemplateToken> tokens;
- tokens.setAutoDelete(TRUE);
+ TemplateTokenStream tokens;
lexer.tokenize(tokens);
TemplateParser parser(engine,name,tokens);
- parser.parse(this,1,QStrList(),m_nodes);
+ parser.parse(this,1,StringVector(),m_nodes);
}
TemplateImpl::~TemplateImpl()
{
- //printf("deleting template %s\n",m_name.data());
+ //printf("deleting template %s\n",qPrint(m_name));
}
-void TemplateImpl::render(FTextStream &ts, TemplateContext *c)
+void TemplateImpl::render(TextStream &ts, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci==0) return; // should not happen
- if (!m_nodes.isEmpty())
+ if (!m_nodes.empty())
{
- TemplateNodeExtend *ne = dynamic_cast<TemplateNodeExtend*>(m_nodes.getFirst());
+ TemplateNodeExtend *ne = dynamic_cast<TemplateNodeExtend*>(m_nodes.front().get());
if (ne==0) // normal template, add blocks to block context
{
TemplateBlockContext *bc = ci->blockContext();
- QListIterator<TemplateNode> li(m_nodes);
- TemplateNode *n;
- for (li.toFirst();(n=li.current());++li)
+ for (const auto &n : m_nodes)
{
- TemplateNodeBlock *nb = dynamic_cast<TemplateNodeBlock*>(n);
+ TemplateNodeBlock *nb = dynamic_cast<TemplateNodeBlock*>(n.get());
if (nb)
{
bc->add(nb);
@@ -5082,63 +5172,66 @@ class TemplateEngine::Private
int m_line = 0;
};
public:
- Private(TemplateEngine *engine) : m_templateCache(17) /*, m_indent(0)*/, m_engine(engine)
+ Private(TemplateEngine *engine) : m_engine(engine)
{
- m_templateCache.setAutoDelete(TRUE);
- m_includeStack.setAutoDelete(TRUE);
}
Template *loadByName(const QCString &fileName,int line)
{
//for (int i=0;i<m_indent;i++) printf(" ");
//m_indent++;
- //printf("loadByName(%s,%d) {\n",fileName.data(),line);
- m_includeStack.append(new IncludeEntry(IncludeEntry::Template,fileName,QCString(),line));
- Template *templ = m_templateCache.find(fileName);
- if (templ==0) // first time template is referenced
+ //printf("loadByName(%s,%d) {\n",qPrint(fileName),line);
+ m_includeStack.emplace_back(IncludeEntry::Template,fileName,QCString(),line);
+ auto kv = m_templateCache.find(fileName.str());
+ if (kv==m_templateCache.end()) // first time template is referenced
{
QCString filePath = m_templateDirName+"/"+fileName;
- QFile f(filePath);
- if (f.open(IO_ReadOnly))
- {
- QFileInfo fi(filePath);
- int size=fi.size();
- QCString data(size+1);
- if (f.readBlock(data.rawData(),size)==size)
- {
- templ = new TemplateImpl(m_engine,filePath,data,m_extension);
- m_templateCache.insert(fileName,templ);
- return templ;
- }
- }
- // fallback to default built-in template
- const QCString data = ResourceMgr::instance().getAsString(fileName);
- if (!data.isEmpty())
- {
- templ = new TemplateImpl(m_engine,fileName,data,m_extension);
- m_templateCache.insert(fileName,templ);
+ std::ifstream f(filePath.str(),std::ifstream::in | std::ifstream::binary);
+ if (f.is_open()) // read template from disk
+ {
+ FileInfo fi(filePath.str());
+ int size=(int)fi.size();
+ QCString data(size+1);
+ f.read(data.rawData(),size);
+ if (!f.fail())
+ {
+ kv = m_templateCache.insert(
+ std::make_pair(fileName.str(),
+ std::make_unique<TemplateImpl>(m_engine,filePath,data,m_extension))).first;
+ }
}
- else
+ else // fallback to default built-in template
{
- err("Could not open template file %s\n",fileName.data());
+ const QCString data = ResourceMgr::instance().getAsString(fileName);
+ if (!data.isEmpty())
+ {
+ kv = m_templateCache.insert(
+ std::make_pair(fileName.str(),
+ std::make_unique<TemplateImpl>(m_engine,fileName,data,m_extension))).first;
+ }
+ else
+ {
+ err("Could not open template file %s\n",qPrint(fileName));
+ }
}
}
- return templ;
+ return kv!=m_templateCache.end() ? kv->second.get() : 0;
}
+
void unload(Template * /*t*/)
{
//(void)t;
//m_indent--;
//for (int i=0;i<m_indent;i++) printf(" ");
//printf("}\n");
- m_includeStack.removeLast();
+ m_includeStack.pop_back();
}
void enterBlock(const QCString &fileName,const QCString &blockName,int line)
{
//for (int i=0;i<m_indent;i++) printf(" ");
//m_indent++;
- //printf("enterBlock(%s,%s,%d) {\n",fileName.data(),blockName.data(),line);
- m_includeStack.append(new IncludeEntry(IncludeEntry::Block,fileName,blockName,line));
+ //printf("enterBlock(%s,%s,%d) {\n",qPrint(fileName),qPrint(blockName),line);
+ m_includeStack.emplace_back(IncludeEntry::Block,fileName,blockName,line);
}
void leaveBlock()
@@ -5146,34 +5239,33 @@ class TemplateEngine::Private
//m_indent--;
//for (int i=0;i<m_indent;i++) printf(" ");
//printf("}\n");
- m_includeStack.removeLast();
+ m_includeStack.pop_back();
}
- void printIncludeContext(const char *fileName,int line) const
+ void printIncludeContext(const QCString &fileName,int line) const
{
- QListIterator<IncludeEntry> li(m_includeStack);
- li.toLast();
- IncludeEntry *ie=li.current();
- while ((ie=li.current()))
+ auto it = m_includeStack.rbegin();
+ while (it!=m_includeStack.rend())
{
- --li;
- IncludeEntry *next=li.current();
- if (ie->type()==IncludeEntry::Template)
+ const IncludeEntry &ie = *it;
+ ++it;
+ const IncludeEntry *next = it!=m_includeStack.rend() ? &(*it) : 0;
+ if (ie.type()==IncludeEntry::Template)
{
if (next)
{
- warn(fileName,line," inside template '%s' included from template '%s' at line %d",ie->fileName().data(),next->fileName().data(),ie->line());
+ warn(fileName,line," inside template '%s' included from template '%s' at line %d",qPrint(ie.fileName()),qPrint(next->fileName()),ie.line());
}
}
- else // ie->type()==IncludeEntry::Block
+ else // ie.type()==IncludeEntry::Block
{
- warn(fileName,line," included by block '%s' inside template '%s' at line %d",ie->blockName().data(),
- ie->fileName().data(),ie->line());
+ warn(fileName,line," included by block '%s' inside template '%s' at line %d",qPrint(ie.blockName()),
+ qPrint(ie.fileName()),ie.line());
}
}
}
- void setOutputExtension(const char *extension)
+ void setOutputExtension(const QCString &extension)
{
m_extension = extension;
}
@@ -5183,16 +5275,16 @@ class TemplateEngine::Private
return m_extension;
}
- void setTemplateDir(const char *dirName)
+ void setTemplateDir(const QCString &dirName)
{
m_templateDirName = dirName;
}
private:
- QDict<Template> m_templateCache;
+ std::unordered_map< std::string, std::unique_ptr<Template> > m_templateCache;
//mutable int m_indent;
TemplateEngine *m_engine = 0;
- QList<IncludeEntry> m_includeStack;
+ std::vector<IncludeEntry> m_includeStack;
QCString m_extension;
QCString m_templateDirName;
};
@@ -5237,12 +5329,12 @@ void TemplateEngine::leaveBlock()
p->leaveBlock();
}
-void TemplateEngine::printIncludeContext(const char *fileName,int line) const
+void TemplateEngine::printIncludeContext(const QCString &fileName,int line) const
{
p->printIncludeContext(fileName,line);
}
-void TemplateEngine::setOutputExtension(const char *extension)
+void TemplateEngine::setOutputExtension(const QCString &extension)
{
p->setOutputExtension(extension);
}
@@ -5252,9 +5344,55 @@ QCString TemplateEngine::outputExtension() const
return p->outputExtension();
}
-void TemplateEngine::setTemplateDir(const char *dirName)
+void TemplateEngine::setTemplateDir(const QCString &dirName)
{
p->setTemplateDir(dirName);
}
+//-----------------------------------------------------------------------------------------
+
+QCString TemplateVariant::listToString() const
+{
+ QCString result="[";
+ const 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="{";
+ const TemplateStructIntf *strukt = toStruct();
+ if (strukt)
+ {
+ bool first=true;
+ for (const auto &s : strukt->fields())
+ {
+ if (!first) result+=",";
+ result+=s;
+ if (dynamic_cast<const TemplateStructWeakRef*>(strukt)==0) // avoid endless recursion
+ {
+ result+=":'";
+ result+=strukt->get(QCString(s)).toString();
+ result+="'";
+ }
+ first=false;
+ }
+ }
+ result+="}";
+ return result;
+}