Skip to content

Commit

Permalink
Added support for elif to the template language
Browse files Browse the repository at this point in the history
  • Loading branch information
Dimitri van Heesch committed Feb 8, 2014
1 parent 196f395 commit ae3a22b
Showing 1 changed file with 55 additions and 14 deletions.
69 changes: 55 additions & 14 deletions src/template.cpp
Expand Up @@ -2022,22 +2022,45 @@ 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()));
if (data.isEmpty())
{
parser->warn(m_templateName,line,"missing argument for if tag");
}
QStrList stopAt;
stopAt.append("endif");
stopAt.append("elif");
stopAt.append("else");
parser->parse(this,line,stopAt,m_trueNodes);
TemplateToken *tok = parser->takeNextToken();

// if 'nodes'
GuardedNodes *guardedNodes = new GuardedNodes;
ExpressionParser ex(parser,line);
m_guardAst = ex.parse(data);
guardedNodes->line = line;
guardedNodes->guardAst = ex.parse(data);
parser->parse(this,line,stopAt,guardedNodes->trueNodes);
m_ifGuardedNodes.append(guardedNodes);
TemplateToken *tok = parser->takeNextToken();

// elif 'nodes'
while (tok && tok->data.left(5)=="elif ")
{
ExpressionParser ex(parser,line);
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();
stopAt.removeLast(); // remove "else"
stopAt.removeLast(); // remove "elif"
parser->parse(this,line,stopAt,m_falseNodes);
parser->removeNextToken(); // skip over endif
}
Expand All @@ -2046,30 +2069,48 @@ class TemplateNodeIf : public TemplateNodeCreator<TemplateNodeIf>
}
~TemplateNodeIf()
{
delete m_guardAst;
}

void render(FTextStream &ts, TemplateContext *c)
{
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
ci->setLocation(m_templateName,m_line);
//printf("TemplateNodeIf::render #trueNodes=%d #falseNodes=%d\n",m_trueNodes.count(),m_falseNodes.count());
if (m_guardAst)
bool processed=FALSE;
QListIterator<GuardedNodes> li(m_ifGuardedNodes);
GuardedNodes *nodes;
for (li.toFirst();(nodes=li.current()) && !processed;++li)
{
TemplateVariant guardValue = m_guardAst->resolve(c);
if (guardValue.toBool()) // guard is true, render corresponding nodes
if (nodes->guardAst)
{
m_trueNodes.render(ts,c);
TemplateVariant guardValue = nodes->guardAst->resolve(c);
if (guardValue.toBool()) // render nodes for the first guard that evaluated to 'true'
{
nodes->trueNodes.render(ts,c);
processed=TRUE;
}
}
else // guard is false, render corresponding nodes
else
{
m_falseNodes.render(ts,c);
ci->warn(m_templateName,nodes->line,"invalid expression for if/elif");
}
}
if (!processed)
{
// all guards are false, render 'else' nodes
m_falseNodes.render(ts,c);
}
}
private:
ExprAst *m_guardAst;
TemplateNodeList m_trueNodes;
struct GuardedNodes
{
GuardedNodes() : guardAst(0) {}
~GuardedNodes() { delete guardAst; }
int line;
ExprAst *guardAst;
TemplateNodeList trueNodes;
};
QList<GuardedNodes> m_ifGuardedNodes;
TemplateNodeList m_falseNodes;
};

Expand Down Expand Up @@ -3474,7 +3515,7 @@ void TemplateParser::parse(
command=="endblock" || command=="endwith" ||
command=="endrecursetree" || command=="endspaceless" ||
command=="endmarkers" || command=="endmsg" ||
command=="endrepeat")
command=="endrepeat" || command=="elif")
{
warn(m_templateName,tok->line,"Found tag '%s' without matching start tag",command.data());
}
Expand Down

0 comments on commit ae3a22b

Please sign in to comment.