nsresult
txSetParam::execute(txExecutionState& aEs)
{
    nsresult rv = NS_OK;
    if (!aEs.mTemplateParams) {
        aEs.mTemplateParams = new txVariableMap;
        NS_ENSURE_TRUE(aEs.mTemplateParams, NS_ERROR_OUT_OF_MEMORY);
    }

    nsRefPtr<txAExprResult> exprRes;
    if (mValue) {
        rv = mValue->evaluate(aEs.getEvalContext(),
                              getter_AddRefs(exprRes));
        NS_ENSURE_SUCCESS(rv, rv);
    }
    else {
        nsAutoPtr<txRtfHandler> rtfHandler(
            static_cast<txRtfHandler*>(aEs.popResultHandler()));
        rv = rtfHandler->getAsRTF(getter_AddRefs(exprRes));
        NS_ENSURE_SUCCESS(rv, rv);
    }

    rv = aEs.mTemplateParams->bindVariable(mName, exprRes);
    NS_ENSURE_SUCCESS(rv, rv);

    return NS_OK;
}
nsresult
txSetVariable::execute(txExecutionState& aEs)
{
    nsresult rv = NS_OK;
    nsRefPtr<txAExprResult> exprRes;
    if (mValue) {
        rv = mValue->evaluate(aEs.getEvalContext(), getter_AddRefs(exprRes));
        NS_ENSURE_SUCCESS(rv, rv);
    }
    else {
        nsAutoPtr<txRtfHandler> rtfHandler(
            static_cast<txRtfHandler*>(aEs.popResultHandler()));
        rv = rtfHandler->getAsRTF(getter_AddRefs(exprRes));
        NS_ENSURE_SUCCESS(rv, rv);
    }

    return aEs.bindVariable(mName, exprRes);
}
示例#3
0
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;
}