nsresult txExecutionState::end(nsresult aResult) { NS_ASSERTION(NS_FAILED(aResult) || mTemplateRules.Length() == 1, "Didn't clean up template rules properly"); if (NS_SUCCEEDED(aResult)) { popTemplateRule(); } else if (!mOutputHandler) { return NS_OK; } return mOutputHandler->endDocument(aResult); }
nsresult txExecutionState::getVariable(int32_t aNamespace, nsIAtom* aLName, txAExprResult*& aResult) { nsresult rv = NS_OK; txExpandedName name(aNamespace, aLName); // look for a local variable if (mLocalVariables) { mLocalVariables->getVariable(name, &aResult); if (aResult) { return NS_OK; } } // look for an evaluated global variable mGlobalVariableValues.getVariable(name, &aResult); if (aResult) { if (aResult == mGlobalVarPlaceholderValue) { // XXX ErrorReport: cyclic variable-value NS_RELEASE(aResult); return NS_ERROR_XSLT_BAD_RECURSION; } return NS_OK; } // Is there perchance a global variable not evaluated yet? txStylesheet::GlobalVariable* var = mStylesheet->getGlobalVariable(name); if (!var) { // XXX ErrorReport: variable doesn't exist in this scope return NS_ERROR_FAILURE; } NS_ASSERTION((var->mExpr && !var->mFirstInstruction) || (!var->mExpr && var->mFirstInstruction), "global variable should have either instruction or expression"); // Is this a stylesheet parameter that has a value? if (var->mIsParam && mGlobalParams) { txIGlobalParameter* param = mGlobalParams->get(name); if (param) { rv = param->getValue(&aResult); NS_ENSURE_SUCCESS(rv, rv); rv = mGlobalVariableValues.bindVariable(name, aResult); if (NS_FAILED(rv)) { NS_RELEASE(aResult); return rv; } return NS_OK; } } // Insert a placeholdervalue to protect against recursion rv = mGlobalVariableValues.bindVariable(name, mGlobalVarPlaceholderValue); NS_ENSURE_SUCCESS(rv, rv); // evaluate the global variable pushEvalContext(mInitialEvalContext); if (var->mExpr) { txVariableMap* oldVars = mLocalVariables; mLocalVariables = nullptr; rv = var->mExpr->evaluate(getEvalContext(), &aResult); mLocalVariables = oldVars; if (NS_FAILED(rv)) { popAndDeleteEvalContextUntil(mInitialEvalContext); return rv; } } else { nsAutoPtr<txRtfHandler> rtfHandler(new txRtfHandler); rv = pushResultHandler(rtfHandler); if (NS_FAILED(rv)) { popAndDeleteEvalContextUntil(mInitialEvalContext); return rv; } rtfHandler.forget(); txInstruction* prevInstr = mNextInstruction; // set return to nullptr to stop execution mNextInstruction = nullptr; rv = runTemplate(var->mFirstInstruction); if (NS_FAILED(rv)) { popAndDeleteEvalContextUntil(mInitialEvalContext); return rv; } pushTemplateRule(nullptr, txExpandedName(), nullptr); rv = txXSLTProcessor::execute(*this); if (NS_FAILED(rv)) { popAndDeleteEvalContextUntil(mInitialEvalContext); return rv; } popTemplateRule(); mNextInstruction = prevInstr; rtfHandler = (txRtfHandler*)popResultHandler(); rv = rtfHandler->getAsRTF(&aResult); if (NS_FAILED(rv)) { popAndDeleteEvalContextUntil(mInitialEvalContext); return rv; } } popEvalContext(); // Remove the placeholder and insert the calculated value mGlobalVariableValues.removeVariable(name); rv = mGlobalVariableValues.bindVariable(name, aResult); if (NS_FAILED(rv)) { NS_RELEASE(aResult); return rv; } return NS_OK; }
nsresult txExecutionState::end(nsresult aResult) { popTemplateRule(); return mOutputHandler->endDocument(aResult); }