void DocumentConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const { QAbstractXmlReceiver *const receiver = context->outputReceiver(); DocumentContentValidator validator(receiver, context, ConstPtr(this)); const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator)); validator.startDocument(); m_operand->evaluateToSequenceReceiver(receiverContext); validator.endDocument(); }
Item::Iterator::Ptr AxisStep::evaluateSequence(const DynamicContext::Ptr &context) const { /* If we don't have a focus, it's either a bug or our parent isn't a Path * that have advanced the focus iterator. Hence, attempt to advance the focus on our own. */ if(!context->contextItem()) context->focusIterator()->next(); Q_ASSERT(context->contextItem()); const QXmlNodeModelIndex::Iterator::Ptr source(context->contextItem().asNode().iterate(m_axis)); return makeItemMappingIterator<Item>(ConstPtr(this), source, context); }
Item PrefixFromQNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const { const QNameValue::Ptr arg(m_operands.first()->evaluateSingleton(context).as<QNameValue>()); if(!arg) return Item(); const QString prefix(context->namePool()->stringForPrefix(arg->qName().prefix())); if(prefix.isEmpty()) return Item(); else return AtomicString::fromValue(context->namePool()->stringForPrefix(arg->qName().prefix())); }
Item EvaluationCache<IsForGlobal>::evaluateSingleton(const DynamicContext::Ptr &context) const { ItemCacheCell &cell = IsForGlobal ? context->globalItemCacheCell(m_varSlot) : context->itemCacheCell(m_varSlot); if(cell.cacheState == ItemCacheCell::Full) return cell.cachedItem; else { Q_ASSERT(cell.cacheState == ItemCacheCell::Empty); cell.cachedItem = m_operand->evaluateSingleton(IsForGlobal ? topFocusContext(context) : context); cell.cacheState = ItemCacheCell::Full; return cell.cachedItem; } }
void ContextNodeChecker::checkTargetNode(const QXmlNodeModelIndex &node, const DynamicContext::Ptr &context, const ReportContext::ErrorCode code) const { if(node.root().kind() != QXmlNodeModelIndex::Document) { context->error(QtXmlPatterns::tr("The root node of the second argument " "to function %1 must be a document " "node. %2 is not a document node.") .arg(formatFunction(context->namePool(), signature()), formatData(node)), code, this); } }
Item AttributeConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item nameItem(m_operand1->evaluateSingleton(context)); const Item content(m_operand2->evaluateSingleton(context)); const QXmlName name(nameItem.as<QNameValue>()->qName()); const QString value(processValue(name, content ? content.stringValue() : QString())); const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(QUrl())); nodeBuilder->attribute(name, QStringRef(&value)); const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument()); context->addNodeModel(nm); return nm->root(QXmlNodeModelIndex()); }
Item::Iterator::Ptr CardinalityVerifier::evaluateSequence(const DynamicContext::Ptr &context) const { const Item::Iterator::Ptr it(m_operand->evaluateSequence(context)); const Item next(it->next()); if(next) { const Item next2(it->next()); if(next2) { if(m_reqCard.allowsMany()) { Item::List start; start.append(next); start.append(next2); return Item::Iterator::Ptr(new InsertionIterator(it, 1, makeListIterator(start))); } else { context->error(wrongCardinality(m_reqCard, Cardinality::twoOrMore()), m_errorCode, this); return CommonValues::emptyIterator; } } else { /* We might be instantiated for the empty sequence. */ if(m_reqCard.isEmpty()) { context->error(wrongCardinality(m_reqCard, Cardinality::twoOrMore()), m_errorCode, this); return CommonValues::emptyIterator; } else return makeSingletonIterator(next); } } else { if(m_reqCard.allowsEmpty()) return CommonValues::emptyIterator; else { context->error(wrongCardinality(m_reqCard, Cardinality::twoOrMore()), m_errorCode, this); return CommonValues::emptyIterator; } } }
Item::Iterator::Ptr Path::evaluateSequence(const DynamicContext::Ptr &context) const { /* Note, we use the old context for m_operand1. */ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context)); const DynamicContext::Ptr focus(context->createFocus()); focus->setFocusIterator(source); const Item::Iterator::Ptr result(makeSequenceMappingIterator<Item>(ConstPtr(this), source, focus)); if(m_checkXPTY0018) { /* This is an expensive code path, but it should happen very rarely. */ enum FoundItem { FoundNone, FoundNode, FoundAtomicValue } hasFound = FoundNone; Item::List whenChecked; Item next(result->next()); while(next) { const FoundItem found = next.isAtomicValue() ? FoundAtomicValue : FoundNode; if(hasFound != FoundNone && hasFound != found) { /* It's an atomic value and we've already found a node. Mixed content. */ context->error(QtXmlPatterns::tr("The last step in a path must contain either nodes " "or atomic values. It cannot be a mixture between the two."), ReportContext::XPTY0018, this); } else hasFound = found; whenChecked.append(next); next = result->next(); } return makeListIterator(whenChecked); } else return result; }
Item DocumentConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const { NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(m_staticBaseURI)); DocumentContentValidator validator(nodeBuilder.data(), context, ConstPtr(this)); const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator)); validator.startDocument(); m_operand->evaluateToSequenceReceiver(receiverContext); validator.endDocument(); const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument()); context->addNodeModel(nm); return nm->root(QXmlNodeModelIndex()); }
void CommentConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const { const QString content(evaluateContent(context)); QAbstractXmlReceiver *const receiver = context->outputReceiver(); receiver->comment(content); }
/** * Performs the actual tracing. */ Item mapToItem(const Item &item, const DynamicContext::Ptr &context) { QTextStream out(stderr); ++m_position; if(m_position == 1) { if(item) { out << qPrintable(m_msg) << " : " << qPrintable(item.stringValue()); } else { out << qPrintable(m_msg) << " : (" << qPrintable(formatType(context->namePool(), CommonSequenceTypes::Empty)) << ")\n"; return Item(); } } else { out << qPrintable(item.stringValue()) << '[' << m_position << "]\n"; } return item; }
void ElementConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const { /* We create an OutputValidator here too. If we're serializing(a common case, unfortunately) * the receiver is already validating in order to catch cases where a computed attribute * constructor is followed by an element constructor, but in the cases where we're not serializing * it's necessary that we validate in this step. */ const Item name(m_operand1->evaluateSingleton(context)); QAbstractXmlReceiver *const receiver = context->outputReceiver(); OutputValidator validator(receiver, context, this); const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator)); receiver->startElement(name.as<QNameValue>()->qName()); m_operand2->evaluateToSequenceReceiver(receiverContext); receiver->endElement(); }
Item CastAs::evaluateSingleton(const DynamicContext::Ptr &context) const { Q_ASSERT(context); const Item val(m_operand->evaluateSingleton(context)); if(val) return cast(val, context); else { /* No item supplied, let's handle the cardinality part. */ if(m_targetType->cardinality().allowsEmpty()) return Item(); else { Q_ASSERT(context); context->error(QtXmlPatterns::tr("Type error in cast, expected %1, " "received %2.") .arg(formatType(Cardinality::exactlyOne())) .arg(formatType(Cardinality::empty())), ReportContext::XPTY0004, this); return Item(); } } }
int NormalizeUnicodeFN::determineNormalizationForm(const DynamicContext::Ptr &context) const { const QString strRepr(m_operands.last()->evaluateSingleton(context).stringValue().trimmed().toUpper()); /* TODO. Put these values in a QHash for faster lookup. Keep thread safety in mind. */ if(strRepr.isEmpty()) return -1; else if(strRepr == QLatin1String("NFC")) return QString::NormalizationForm_C; else if(strRepr == QLatin1String("NFD")) return QString::NormalizationForm_D; else if(strRepr == QLatin1String("NFKC")) return QString::NormalizationForm_KC; else if(strRepr == QLatin1String("NFKD")) return QString::NormalizationForm_KD; else { /* What form is FULLY_NORMALIZED? Is a code path available for that somewhere? */ context->error(QtXmlPatterns::tr("The normalization form %1 is " "unsupported. The supported forms are " "%2, %3, %4, and %5, and none, i.e. " "the empty string (no normalization).") .arg(formatKeyword(strRepr)) .arg(formatKeyword("NFC")) .arg(formatKeyword("NFD")) .arg(formatKeyword("NFKC")) .arg(formatKeyword("NFKD")), ReportContext::FOCH0003, this); return QString::NormalizationForm_C; /* Silence compiler warning. */ } }
Item TextNodeConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item chars(m_operand->evaluateSingleton(context)); if(!chars) return Item(); const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(QUrl())); const QString &v = chars.stringValue(); nodeBuilder->characters(QStringRef(&v)); const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument()); context->addNodeModel(nm); return nm->root(QXmlNodeModelIndex()); }
Item CodepointsToStringFN::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context)); if(!it) return CommonValues::EmptyString; QString retval; Item item(it->next()); while(item) { const qint32 cp = static_cast<qint32>(item.as<Numeric>()->toInteger()); if(!isValidXML10Char(cp)) { context->error(QtXmlPatterns::tr("%1 is not a valid XML 1.0 character.") .arg(formatData(QLatin1String("0x") + QString::number(cp, 16))), ReportContext::FOCH0001, this); return CommonValues::EmptyString; } retval.append(QChar(cp)); item = it->next(); } return AtomicString::fromValue(retval); }
Item ElementConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item name(m_operand1->evaluateSingleton(context)); const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(m_staticBaseURI)); OutputValidator validator(nodeBuilder.data(), context, this, m_isXSLT); const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator)); nodeBuilder->startElement(name.as<QNameValue>()->qName()); m_operand2->evaluateToSequenceReceiver(receiverContext); nodeBuilder->endElement(); const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument()); context->addNodeModel(nm); return nm->root(QXmlNodeModelIndex()); }
bool DocAvailableFN::evaluateEBV(const DynamicContext::Ptr &context) const { const Item itemURI(m_operands.first()->evaluateSingleton(context)); /* 15.5.4 fn:doc reads: "If $uri is the empty sequence, the result is an empty sequence." * Hence, we return false for the empty sequence, because this doesn't hold true: * "If this function returns true, then calling fn:doc($uri) within * the same execution scope must return a document node."(15.5.5 fn:doc-available) */ if(!itemURI) return false; /* These two lines are duplicated in DocFN::evaluateSingleton(), as part * of a workaround for solaris-cc-64. */ const QUrl mayRela(AnyURI::toQUrl<ReportContext::FODC0005>(itemURI.stringValue(), context, this)); const QUrl uri(context->resolveURI(mayRela, staticBaseURI())); Q_ASSERT(!uri.isRelative()); return context->resourceLoader()->isDocumentAvailable(uri); }
DynamicContext::Ptr UserFunctionCallsite::bindVariables(const DynamicContext::Ptr &context) const { const DynamicContext::Ptr stackContext(context->createStack()); Q_ASSERT(stackContext); const Expression::List::const_iterator end(m_operands.constEnd()); Expression::List::const_iterator it(m_operands.constBegin()); VariableSlotID slot = m_expressionSlotOffset; for(; it != end; ++it) { stackContext->setExpressionVariable(slot, Expression::Ptr(new DynamicContextStore(*it, context))); ++slot; } return stackContext; }
Item::Iterator::Ptr EvaluationCache<IsForGlobal>::evaluateSequence(const DynamicContext::Ptr &context) const { ItemSequenceCacheCell::Vector &cells = IsForGlobal ? context->globalItemSequenceCacheCells(m_varSlot) : context->itemSequenceCacheCells(m_varSlot); ItemSequenceCacheCell &cell = cells[m_varSlot]; if(cell.inUse) { context->error(QtXmlPatterns::tr("Circularity detected"), ReportContext::XTDE0640, this); } switch(cell.cacheState) { case ItemSequenceCacheCell::Full: { /** * We don't use makeListIterator() here because the MIPSPro compiler can't handle it. */ return Item::Iterator::Ptr(new ListIterator<Item, Item::List>(cell.cachedItems)); } case ItemSequenceCacheCell::Empty: { cell.inUse = true; cell.sourceIterator = m_operand->evaluateSequence(IsForGlobal ? topFocusContext(context) : context); cell.cacheState = ItemSequenceCacheCell::PartiallyPopulated; /* Fallthrough. */ } case ItemSequenceCacheCell::PartiallyPopulated: { cell.inUse = false; Q_ASSERT_X(cells.at(m_varSlot).sourceIterator, Q_FUNC_INFO, "This trigger for a cache bug which hasn't yet been analyzed."); return Item::Iterator::Ptr(new CachingIterator(cells, m_varSlot, IsForGlobal ? topFocusContext(context) : context)); } default: { Q_ASSERT_X(false, Q_FUNC_INFO, "This path is not supposed to be run."); return Item::Iterator::Ptr(); } } }
void AttributeConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const { QAbstractXmlReceiver *const receiver = context->outputReceiver(); const Item nameItem(m_operand1->evaluateSingleton(context)); const Item content(m_operand2->evaluateSingleton(context)); const QXmlName name(nameItem.as<QNameValue>()->qName()); const QString value(processValue(name, content ? content.stringValue() : QString())); receiver->attribute(name, QStringRef(&value)); }
Item CardinalityVerifier::evaluateSingleton(const DynamicContext::Ptr &context) const { if(m_allowsMany) { const Item::Iterator::Ptr it(m_operand->evaluateSequence(context)); const Item item(it->next()); if(item) { if(it->next()) { context->error(wrongCardinality(m_reqCard, Cardinality::twoOrMore()), m_errorCode, this); return Item(); } else return item; } else if(m_reqCard.allowsEmpty()) return Item(); else { context->error(wrongCardinality(m_reqCard), m_errorCode, this); return Item(); } } else { const Item item(m_operand->evaluateSingleton(context)); if(item) return item; else if(m_reqCard.allowsEmpty()) return Item(); else { context->error(wrongCardinality(m_reqCard), m_errorCode, this); return Item(); } } }
Item DocFN::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item itemURI(m_operands.first()->evaluateSingleton(context)); if(!itemURI) return Item(); /* These two lines were previously in a separate function but are now duplicated * in DocAvailableFN::evaluateEBV() and DocFN::typeCheck(), * as part of a workaround for solaris-cc-64. DocFN::typeCheck() is in qsequencefns.cpp * as part of that workaround. */ const QUrl mayRela(AnyURI::toQUrl<ReportContext::FODC0005>(itemURI.stringValue(), context, this)); const QUrl uri(context->resolveURI(mayRela, staticBaseURI())); Q_ASSERT(uri.isValid()); Q_ASSERT(!uri.isRelative()); const Item doc(context->resourceLoader()->openDocument(uri, context)); return doc; }
void Expression::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const { QAbstractXmlReceiver *const receiver = context->outputReceiver(); const Item::Iterator::Ptr it(evaluateSequence(context)); Item next(it->next()); while(next) { receiver->item(next); next = it->next(); } }
Item QNameConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const { Q_ASSERT(context); const QString lexQName(m_operand->evaluateSingleton(context).stringValue()); const QXmlName expQName(expandQName<DynamicContext::Ptr, ReportContext::XQDY0074, ReportContext::XQDY0074>(lexQName, context, m_nsResolver, this)); return toItem(QNameValue::fromValue(context->namePool(), expQName)); }
PatternPlatform::Flags PatternPlatform::parseFlags(const QString &flags, const DynamicContext::Ptr &context) const { if(flags.isEmpty()) return NoFlags; const PatternFlag::Hash flagDescrs(flagDescriptions()); const int len = flags.length(); Flags retval = NoFlags; for(int i = 0; i < len; ++i) { const QChar flag(flags.at(i)); const Flag specified = flagDescrs.value(flag).flag; if(specified != NoFlags) { retval |= specified; continue; } /* Generate a nice error message. */ QString message(QtXmlPatterns::tr("%1 is an invalid flag for regular expressions. Valid flags are:") .arg(formatKeyword(flag))); /* This is formatting, so don't bother translators with it. */ message.append(QLatin1Char('\n')); const PatternFlag::Hash::const_iterator end(flagDescrs.constEnd()); PatternFlag::Hash::const_iterator it(flagDescrs.constBegin()); for(; it != end;) { // TODO handle bidi correctly // TODO format this with rich text(list/table) message.append(formatKeyword(it.key())); message.append(QLatin1String(" - ")); message.append(it.value().description); ++it; if(it != end) message.append(QLatin1Char('\n')); } context->error(message, ReportContext::FORX0001, this); return NoFlags; } return retval; }
TemplateMode::Ptr ApplyTemplate::effectiveMode(const DynamicContext::Ptr &context) const { if(m_mode) return m_mode; else { const TemplateMode::Ptr currentMode(context->currentTemplateMode()); if(currentMode) return currentMode; else return m_defaultMode; } }
void TextNodeConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const { const Item item(m_operand->evaluateSingleton(context)); QAbstractXmlReceiver *const receiver = context->outputReceiver(); if(item) { const QString &v = item.stringValue(); receiver->characters(QStringRef(&v)); } else receiver->characters(QStringRef()); }
Item Path::evaluateSingleton(const DynamicContext::Ptr &context) const { /* This function is called if both operands' cardinality is exactly-one. Therefore * we manually go forward in the focus by calling next(). * * We don't check for XPTY0018, only in evaluateSequence(), since if we're guaranteed * to evaluate to one item, we can only evaluate to one node or one atomic value. */ /* Note, we use the old context for m_operand1. */ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context)); const DynamicContext::Ptr focus(context->createFocus()); focus->setFocusIterator(source); /* This test is needed because if the focus is empty, we don't want to(nor can't) evaluate * the next step. */ // TODO Why are we at all invoked then? if(source->next()) return m_operand2->evaluateSingleton(focus); else return Item(); }
Item ErrorFN::evaluateSingleton(const DynamicContext::Ptr &context) const { QString msg; switch(m_operands.count()) { case 0: /* No args. */ { context->error(QtXmlPatterns::tr("%1 was called.").arg(formatFunction(context->namePool(), signature())), ReportContext::FOER0000, this); return Item(); } case 3: /* Fallthrough, we don't use the 'error object' param. */ case 2: msg = m_operands.at(1)->evaluateSingleton(context).stringValue(); /* Fall through. */ case 1: { const QNameValue::Ptr qName(m_operands.first()->evaluateSingleton(context).as<QNameValue>()); if(qName) context->error(msg, qName->qName(), this); else context->error(msg, ReportContext::FOER0000, this); return Item(); } default: { Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid number of arguments passed to fn:error."); return Item(); } } }