nsresult
txStylesheet::doneCompiling()
{
    nsresult rv = NS_OK;
    // Collect all importframes into a single ordered list
    txListIterator frameIter(&mImportFrames);
    rv = frameIter.addAfter(mRootFrame);
    NS_ENSURE_SUCCESS(rv, rv);
    
    mRootFrame = nullptr;
    frameIter.next();
    rv = addFrames(frameIter);
    NS_ENSURE_SUCCESS(rv, rv);

    // Loop through importframes in decreasing-precedence-order and process
    // all items
    frameIter.reset();
    ImportFrame* frame;
    while ((frame = static_cast<ImportFrame*>(frameIter.next()))) {
        nsTArray<txStripSpaceTest*> frameStripSpaceTests;

        txListIterator itemIter(&frame->mToplevelItems);
        itemIter.resetToEnd();
        txToplevelItem* item;
        while ((item = static_cast<txToplevelItem*>(itemIter.previous()))) {
            switch (item->getType()) {
                case txToplevelItem::attributeSet:
                {
                    rv = addAttributeSet(static_cast<txAttributeSetItem*>
                                                    (item));
                    NS_ENSURE_SUCCESS(rv, rv);
                    break;
                }
                case txToplevelItem::dummy:
                case txToplevelItem::import:
                {
                    break;
                }
                case txToplevelItem::output:
                {
                    mOutputFormat.merge(static_cast<txOutputItem*>(item)->mFormat);
                    break;
                }
                case txToplevelItem::stripSpace:
                {
                    rv = addStripSpace(static_cast<txStripSpaceItem*>(item),
                                       frameStripSpaceTests);
                    NS_ENSURE_SUCCESS(rv, rv);
                    break;
                }
                case txToplevelItem::templ:
                {
                    rv = addTemplate(static_cast<txTemplateItem*>(item),
                                     frame);
                    NS_ENSURE_SUCCESS(rv, rv);

                    break;
                }
                case txToplevelItem::variable:
                {
                    rv = addGlobalVariable(static_cast<txVariableItem*>
                                                      (item));
                    NS_ENSURE_SUCCESS(rv, rv);

                    break;
                }
            }
            delete item;
            itemIter.remove(); //remove() moves to the previous
            itemIter.next();
        }
        if (!mStripSpaceTests.AppendElements(frameStripSpaceTests)) {
            return NS_ERROR_OUT_OF_MEMORY;
        }
        
        frameStripSpaceTests.Clear();
    }

    if (!mDecimalFormats.get(txExpandedName())) {
        nsAutoPtr<txDecimalFormat> format(new txDecimalFormat);
        NS_ENSURE_TRUE(format, NS_ERROR_OUT_OF_MEMORY);
        
        rv = mDecimalFormats.add(txExpandedName(), format);
        NS_ENSURE_SUCCESS(rv, rv);
        
        format.forget();
    }

    return NS_OK;
}
nsresult
txPushNullTemplateRule::execute(txExecutionState& aEs)
{
    aEs.pushTemplateRule(nullptr, txExpandedName(), nullptr);
    return NS_OK;
}
Example #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;
}
nsresult
txPushNullTemplateRule::execute(txExecutionState& aEs)
{
    return aEs.pushTemplateRule(nsnull, txExpandedName(), nsnull);
}