bool PreprocessContext::process(const QString &in, QString *out, QString *errorMessage) { out->clear(); if (in.isEmpty()) return true; out->reserve(in.size()); reset(); const QChar newLine = QLatin1Char('\n'); const QStringList lines = in.split(newLine, QString::KeepEmptyParts); const int lineCount = lines.size(); bool first = true; for (int l = 0; l < lineCount; l++) { // Check for element of the stack (be it dummy, else something is wrong). if (m_sectionStack.isEmpty()) { if (errorMessage) *errorMessage = msgEmptyStack(l); return false; } QString expression; bool expressionValue = false; PreprocessStackEntry &top = m_sectionStack.back(); switch (preprocessorLine(lines.at(l), &expression)) { case IfSection: // '@If': Push new section if (top.condition) { if (!TemplateEngine::evaluateBooleanJavaScriptExpression(m_scriptEngine, expression, &expressionValue, errorMessage)) { if (errorMessage) *errorMessage = QString::fromLatin1("Error in @if at %1: %2") .arg(l + 1).arg(*errorMessage); return false; } } m_sectionStack.push(PreprocessStackEntry(IfSection, top.condition, expressionValue, expressionValue)); break; case ElsifSection: // '@elsif': Check condition. if (top.section != IfSection && top.section != ElsifSection) { if (errorMessage) *errorMessage = QString::fromLatin1("No preceding @if found for @elsif at %1") .arg(l + 1); return false; } if (top.parentEnabled) { if (!TemplateEngine::evaluateBooleanJavaScriptExpression(m_scriptEngine, expression, &expressionValue, errorMessage)) { if (errorMessage) *errorMessage = QString::fromLatin1("Error in @elsif at %1: %2") .arg(l + 1).arg(*errorMessage); return false; } } top.section = ElsifSection; // ignore consecutive '@elsifs' once something matched if (top.anyIfClauseMatched) { top.condition = false; } else { if ( (top.condition = expressionValue) ) top.anyIfClauseMatched = true; } break; case ElseSection: // '@else': Check condition. if (top.section != IfSection && top.section != ElsifSection) { if (errorMessage) *errorMessage = QString::fromLatin1("No preceding @if/@elsif found for @else at %1") .arg(l + 1); return false; } expressionValue = top.parentEnabled && !top.anyIfClauseMatched; top.section = ElseSection; top.condition = expressionValue; break; case EndifSection: // '@endif': Discard section. m_sectionStack.pop(); break; case OtherSection: // Rest: Append according to current condition. if (top.condition) { if (first) first = false; else out->append(newLine); out->append(lines.at(l)); } break; } // switch section } // for lines return true; }