diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-23 09:18:55 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-03-23 09:18:55 (GMT) |
commit | e5fcad302d86d316390c6b0f62759a067313e8a9 (patch) | |
tree | c2afbf6f1066b6ce261f14341cf6d310e5595bc1 /src/xmlpatterns/functions | |
download | Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.zip Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.gz Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.bz2 |
Long live Qt 4.5!
Diffstat (limited to 'src/xmlpatterns/functions')
98 files changed, 13837 insertions, 0 deletions
diff --git a/src/xmlpatterns/functions/functions.pri b/src/xmlpatterns/functions/functions.pri new file mode 100644 index 0000000..7add860 --- /dev/null +++ b/src/xmlpatterns/functions/functions.pri @@ -0,0 +1,96 @@ +HEADERS += $$PWD/qabstractfunctionfactory_p.h \ + $$PWD/qaccessorfns_p.h \ + $$PWD/qaggregatefns_p.h \ + $$PWD/qaggregator_p.h \ + $$PWD/qassemblestringfns_p.h \ + $$PWD/qbooleanfns_p.h \ + $$PWD/qcomparescaseaware_p.h \ + $$PWD/qcomparestringfns_p.h \ + $$PWD/qcomparingaggregator_p.h \ + $$PWD/qconstructorfunctionsfactory_p.h \ + $$PWD/qcontextfns_p.h \ + $$PWD/qcurrentfn_p.h \ + $$PWD/qdatetimefn_p.h \ + $$PWD/qdatetimefns_p.h \ + $$PWD/qdeepequalfn_p.h \ + $$PWD/qdocumentfn_p.h \ + $$PWD/qelementavailablefn_p.h \ + $$PWD/qerrorfn_p.h \ + $$PWD/qfunctionargument_p.h \ + $$PWD/qfunctionavailablefn_p.h \ + $$PWD/qfunctioncall_p.h \ + $$PWD/qfunctionfactorycollection_p.h \ + $$PWD/qfunctionfactory_p.h \ + $$PWD/qfunctionsignature_p.h \ + $$PWD/qgenerateidfn_p.h \ + $$PWD/qnodefns_p.h \ + $$PWD/qnumericfns_p.h \ + $$PWD/qpatternmatchingfns_p.h \ + $$PWD/qpatternplatform_p.h \ + $$PWD/qqnamefns_p.h \ + $$PWD/qresolveurifn_p.h \ + $$PWD/qsequencefns_p.h \ + $$PWD/qsequencegeneratingfns_p.h \ + $$PWD/qstaticbaseuricontainer_p.h \ + $$PWD/qstaticnamespacescontainer_p.h \ + $$PWD/qstringvaluefns_p.h \ + $$PWD/qsubstringfns_p.h \ + $$PWD/qsystempropertyfn_p.h \ + $$PWD/qtimezonefns_p.h \ + $$PWD/qtracefn_p.h \ + $$PWD/qtypeavailablefn_p.h \ + $$PWD/qunparsedentitypublicidfn_p.h \ + $$PWD/qunparsedentityurifn_p.h \ + $$PWD/qunparsedtextavailablefn_p.h \ + $$PWD/qunparsedtextfn_p.h \ + $$PWD/qcontextnodechecker_p.h \ + $$PWD/qxpath10corefunctions_p.h \ + $$PWD/qxpath20corefunctions_p.h \ + $$PWD/qxslt20corefunctions_p.h + +SOURCES += $$PWD/qabstractfunctionfactory.cpp \ + $$PWD/qaccessorfns.cpp \ + $$PWD/qaggregatefns.cpp \ + $$PWD/qaggregator.cpp \ + $$PWD/qassemblestringfns.cpp \ + $$PWD/qbooleanfns.cpp \ + $$PWD/qcomparescaseaware.cpp \ + $$PWD/qcomparestringfns.cpp \ + $$PWD/qconstructorfunctionsfactory.cpp \ + $$PWD/qcontextfns.cpp \ + $$PWD/qcontextnodechecker.cpp \ + $$PWD/qcurrentfn.cpp \ + $$PWD/qdatetimefn.cpp \ + $$PWD/qdeepequalfn.cpp \ + $$PWD/qdocumentfn.cpp \ + $$PWD/qelementavailablefn.cpp \ + $$PWD/qerrorfn.cpp \ + $$PWD/qfunctionargument.cpp \ + $$PWD/qfunctionavailablefn.cpp \ + $$PWD/qfunctioncall.cpp \ + $$PWD/qfunctionfactorycollection.cpp \ + $$PWD/qfunctionfactory.cpp \ + $$PWD/qfunctionsignature.cpp \ + $$PWD/qgenerateidfn.cpp \ + $$PWD/qnodefns.cpp \ + $$PWD/qnumericfns.cpp \ + $$PWD/qpatternmatchingfns.cpp \ + $$PWD/qpatternplatform.cpp \ + $$PWD/qqnamefns.cpp \ + $$PWD/qresolveurifn.cpp \ + $$PWD/qsequencefns.cpp \ + $$PWD/qsequencegeneratingfns.cpp \ + $$PWD/qstaticnamespacescontainer.cpp \ + $$PWD/qstringvaluefns.cpp \ + $$PWD/qsubstringfns.cpp \ + $$PWD/qsystempropertyfn.cpp \ + $$PWD/qtimezonefns.cpp \ + $$PWD/qtracefn.cpp \ + $$PWD/qtypeavailablefn.cpp \ + $$PWD/qunparsedentitypublicidfn.cpp \ + $$PWD/qunparsedentityurifn.cpp \ + $$PWD/qunparsedtextavailablefn.cpp \ + $$PWD/qunparsedtextfn.cpp \ + $$PWD/qxpath10corefunctions.cpp \ + $$PWD/qxpath20corefunctions.cpp \ + $$PWD/qxslt20corefunctions.cpp diff --git a/src/xmlpatterns/functions/qabstractfunctionfactory.cpp b/src/xmlpatterns/functions/qabstractfunctionfactory.cpp new file mode 100644 index 0000000..6d901aa --- /dev/null +++ b/src/xmlpatterns/functions/qabstractfunctionfactory.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpatternistlocale_p.h" + +#include "qabstractfunctionfactory_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Expression::Ptr AbstractFunctionFactory::createFunctionCall(const QXmlName name, + const Expression::List &args, + const StaticContext::Ptr &context, + const SourceLocationReflection *const r) +{ + const FunctionSignature::Ptr sign(retrieveFunctionSignature(context->namePool(), name)); + + if(!sign) /* The function doesn't exist(at least not in this factory). */ + return Expression::Ptr(); + + /* May throw. */ + verifyArity(sign, context, args.count(), r); + + /* Ok, the function does exist and the arity is correct. */ + return retrieveExpression(name, args, sign); +} + +void AbstractFunctionFactory::verifyArity(const FunctionSignature::Ptr &s, + const StaticContext::Ptr &context, + const xsInteger arity, + const SourceLocationReflection *const r) const +{ + /* Same code in both branches, but more specific error messages in order + * to improve usability. */ + if(s->maximumArguments() != FunctionSignature::UnlimitedArity && + arity > s->maximumArguments()) + { + context->error(QtXmlPatterns::tr("%1 takes at most %n argument(s). " + "%2 is therefore invalid.", 0, s->maximumArguments()) + .arg(formatFunction(context->namePool(), s)) + .arg(arity), + ReportContext::XPST0017, + r); + return; + } + + if(arity < s->minimumArguments()) + { + context->error(QtXmlPatterns::tr("%1 requires at least %n argument(s). " + "%2 is therefore invalid.", 0, s->minimumArguments()) + .arg(formatFunction(context->namePool(), s)) + .arg(arity), + ReportContext::XPST0017, + r); + return; + } +} + +FunctionSignature::Hash AbstractFunctionFactory::functionSignatures() const +{ + return m_signatures; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qabstractfunctionfactory_p.h b/src/xmlpatterns/functions/qabstractfunctionfactory_p.h new file mode 100644 index 0000000..b988658 --- /dev/null +++ b/src/xmlpatterns/functions/qabstractfunctionfactory_p.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AbstractFunctionFactory_H +#define Patternist_AbstractFunctionFactory_H + +#include "qcommonnamespaces_p.h" +#include "qfunctionfactory_p.h" +#include "qfunctionsignature_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Supplies convenience code for the function factories. + * + * @ingroup Patternist_functions + * @see XPath10CoreFunctions + * @see XPath20CoreFunctions + * @see XSLT10CoreFunctions + * @author Vincent Ricard <magic@magicninja.org> + */ + class AbstractFunctionFactory : public FunctionFactory + { + public: + virtual Expression::Ptr createFunctionCall(const QXmlName name, + const Expression::List &arguments, + const StaticContext::Ptr &context, + const SourceLocationReflection *const r); + + virtual FunctionSignature::Hash functionSignatures() const; + + protected: + /** + * This function is responsible for creating the actual Expression, corresponding + * to @p localName and the function signature @p sign. It is called by + * createFunctionCall(), once it have been determined the function actually + * exists and have the correct arity. + * + * This function will only be called for names in the @c fn namespace. + */ + virtual Expression::Ptr retrieveExpression(const QXmlName name, + const Expression::List &args, + const FunctionSignature::Ptr &sign) const = 0; + + inline + FunctionSignature::Ptr addFunction(const QXmlName::LocalNameCode localName, + const FunctionSignature::Arity minArgs, + const FunctionSignature::Arity maxArgs, + const SequenceType::Ptr &returnType, + const Expression::Properties props) + { + return addFunction(localName, + minArgs, + maxArgs, + returnType, + Expression::IDIgnorableExpression, + props); + } + + FunctionSignature::Ptr addFunction(const QXmlName::LocalNameCode &localName, + const FunctionSignature::Arity minArgs, + const FunctionSignature::Arity maxArgs, + const SequenceType::Ptr &returnType, + const Expression::ID id = Expression::IDIgnorableExpression, + const Expression::Properties props = Expression::Properties(), + const StandardNamespaces::ID ns = StandardNamespaces::fn) + { + const QXmlName name(ns, localName); + + const FunctionSignature::Ptr s(new FunctionSignature(name, minArgs, maxArgs, + returnType, props, id)); + + m_signatures.insert(name, s); + return s; + } + + static inline QXmlName::LocalNameCode argument(const NamePool::Ptr &np, const char *const name) + { + return np->allocateLocalName(QLatin1String(name)); + } + + FunctionSignature::Hash m_signatures; + + private: + /** + * @short Determines whether @p arity is a valid number of + * arguments for the function with signature @p sign. + * + * If it is not, a static error with error code ReportContext::XPST0017 + * is issued via @p context. + */ + void verifyArity(const FunctionSignature::Ptr &sign, + const StaticContext::Ptr &context, + const xsInteger arity, + const SourceLocationReflection *const r) const; + + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qaccessorfns.cpp b/src/xmlpatterns/functions/qaccessorfns.cpp new file mode 100644 index 0000000..8ff9ef4 --- /dev/null +++ b/src/xmlpatterns/functions/qaccessorfns.cpp @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qanyuri_p.h" +#include "qboolean_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonvalues_p.h" +#include "qliteral_p.h" +#include "qitem_p.h" +#include "qqnamevalue_p.h" +#include "qatomicstring_p.h" + +#include "qaccessorfns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item NodeNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item item(m_operands.first()->evaluateSingleton(context)); + + if(item) + { + const QXmlName name(item.asNode().name()); + + if(name.isNull()) + return Item(); + else + return toItem(QNameValue::fromValue(context->namePool(), name)); + } + else + return Item(); +} + +Item NilledFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item item(m_operands.first()->evaluateSingleton(context)); + + if(item && item.asNode().kind() == QXmlNodeModelIndex::Element) + { + /* We have no access to the PSVI -- always return false. */ + return CommonValues::BooleanFalse; + } + else + return Item(); +} + +Item StringFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item item(m_operands.first()->evaluateSingleton(context)); + + if(item) + return AtomicString::fromValue(item.stringValue()); + else + return CommonValues::EmptyString; +} + +Expression::Ptr StringFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + const Expression::Ptr me(FunctionCall::typeCheck(context, reqType)); + if(me != this) + return me; + + if(BuiltinTypes::xsString->xdtTypeMatches(m_operands.first()->staticType()->itemType())) + return m_operands.first(); /* No need for string(), it's already a string. */ + else + return me; +} + +Item BaseURIFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item node(m_operands.first()->evaluateSingleton(context)); + + if(node) + { + const QUrl base(node.asNode().baseUri()); + + if(base.isEmpty()) + return Item(); + else if(base.isValid()) + { + Q_ASSERT_X(!base.isRelative(), Q_FUNC_INFO, + "The base URI must be absolute."); + return toItem(AnyURI::fromValue(base)); + } + else + return Item(); + } + else + return Item(); +} + +Item DocumentURIFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item node(m_operands.first()->evaluateSingleton(context)); + + if(node) + { + const QUrl documentURI(node.asNode().documentUri()); + + if(documentURI.isValid()) + { + if(documentURI.isEmpty()) + return Item(); + else + { + Q_ASSERT_X(!documentURI.isRelative(), Q_FUNC_INFO, + "The document URI must be absolute."); + return toItem(AnyURI::fromValue(documentURI)); + } + } + else + return Item(); + } + else + return Item(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qaccessorfns_p.h b/src/xmlpatterns/functions/qaccessorfns_p.h new file mode 100644 index 0000000..61c986a --- /dev/null +++ b/src/xmlpatterns/functions/qaccessorfns_p.h @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AccessorFNs_H +#define Patternist_AccessorFNs_H + +#include "qfunctioncall_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#accessors">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 2 Accessors</a>. + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements the function <tt>fn:node-name()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class NodeNameFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:nilled()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class NilledFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:string()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class StringFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + }; + + /** + * @short Implements the function <tt>fn:base-uri()</tt>. + * + * @author Frans Englich <fenglich@trolltech.com> + */ + class BaseURIFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:document-uri()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class DocumentURIFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qaggregatefns.cpp b/src/xmlpatterns/functions/qaggregatefns.cpp new file mode 100644 index 0000000..99302ba --- /dev/null +++ b/src/xmlpatterns/functions/qaggregatefns.cpp @@ -0,0 +1,316 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstractfloat_p.h" +#include "qarithmeticexpression_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qdecimal_p.h" +#include "qgenericsequencetype_p.h" +#include "qinteger_p.h" +#include "qoptimizerblocks_p.h" +#include "qsequencefns_p.h" +#include "quntypedatomicconverter_p.h" + +#include "qaggregatefns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item CountFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return Integer::fromValue(m_operands.first()->evaluateSequence(context)->count()); +} + +Expression::Ptr CountFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + if(*CommonSequenceTypes::EBV->itemType() == *reqType->itemType()) + { + return ByIDCreator::create(IDExistsFN, operands(), context, this)->typeCheck(context, reqType); + } + else + return FunctionCall::typeCheck(context, reqType); +} + +Expression::Ptr CountFN::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(FunctionCall::compress(context)); + if(me != this) + return me; + + const Cardinality card(m_operands.first()->staticType()->cardinality()); + if(card.isExactlyOne()) + return wrapLiteral(CommonValues::IntegerOne, context, this); + else if(card.isEmpty()) + { + /* One might think that if the operand is (), that compress() would have + * evaluated us and therefore this line never be reached, but "()" can + * be combined with the DisableElimination flag. */ + return wrapLiteral(CommonValues::IntegerZero, context, this); + } + else if(card.isExact()) + return wrapLiteral(Integer::fromValue(card.minimum()), context, this); + else + return me; +} + +Expression::Ptr AddingAggregate::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + const Expression::Ptr me(FunctionCall::typeCheck(context, reqType)); + ItemType::Ptr t1(m_operands.first()->staticType()->itemType()); + + if(*CommonSequenceTypes::Empty == *t1) + return me; + else if(*BuiltinTypes::xsAnyAtomicType == *t1 || + *BuiltinTypes::numeric == *t1) + return me; + else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1)) + { + m_operands.replace(0, Expression::Ptr(new UntypedAtomicConverter(m_operands.first(), + BuiltinTypes::xsDouble))); + t1 = m_operands.first()->staticType()->itemType(); + } + else if(!BuiltinTypes::numeric->xdtTypeMatches(t1) && + !BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t1) && + !BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t1)) + { + /* Translator, don't translate the type names. */ + context->error(QtXmlPatterns::tr("The first argument to %1 cannot be " + "of type %2. It must be a numeric " + "type, xs:yearMonthDuration or " + "xs:dayTimeDuration.") + .arg(formatFunction(context->namePool(), signature())) + .arg(formatType(context->namePool(), + m_operands.first()->staticType())), + ReportContext::FORG0006, this); + } + + if(!m_operands.first()->staticType()->cardinality().allowsMany()) + return m_operands.first(); + + /* We know fetchMathematician won't attempt a rewrite of the operand, so this is safe. */ + m_mather = ArithmeticExpression::fetchMathematician(m_operands.first(), m_operands.first(), + AtomicMathematician::Add, true, context, + this, + ReportContext::FORG0006); + return me; +} + +Item AvgFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context)); + Item sum(it->next()); + + xsInteger count = 0; + while(sum) + { + ++count; + const Item next(it->next()); + if(!next) + break; + + sum = ArithmeticExpression::flexiblyCalculate(sum, AtomicMathematician::Add, + next, m_adder, context, + this, + ReportContext::FORG0006); + }; + + if(!sum) + return Item(); + + /* Note that we use the same m_mather which was used for adding, + * can be worth to think about. */ + return ArithmeticExpression::flexiblyCalculate(sum, AtomicMathematician::Div, + Integer::fromValue(count), + m_divider, context, + this, + ReportContext::FORG0006); +} + +Expression::Ptr AvgFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + const Expression::Ptr me(FunctionCall::typeCheck(context, reqType)); + ItemType::Ptr t1(m_operands.first()->staticType()->itemType()); + + if(*CommonSequenceTypes::Empty == *t1) + return me; + else if(*BuiltinTypes::xsAnyAtomicType == *t1 || + *BuiltinTypes::numeric == *t1) + return me; + else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1)) + { + m_operands.replace(0, Expression::Ptr(new UntypedAtomicConverter(m_operands.first(), + BuiltinTypes::xsDouble))); + t1 = m_operands.first()->staticType()->itemType(); + } + else if(!BuiltinTypes::numeric->xdtTypeMatches(t1) && + !BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t1) && + !BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t1)) + { + /* Translator, don't translate the type names. */ + context->error(QtXmlPatterns::tr("The first argument to %1 cannot be " + "of type %2. It must be of type %3, " + "%4, or %5.") + .arg(signature()) + .arg(formatType(context->namePool(), m_operands.first()->staticType())) + .arg(formatType(context->namePool(), BuiltinTypes::numeric)) + .arg(formatType(context->namePool(), BuiltinTypes::xsYearMonthDuration)) + .arg(formatType(context->namePool(), BuiltinTypes::xsDayTimeDuration)), + ReportContext::FORG0006, this); + } + + if(!m_operands.first()->staticType()->cardinality().allowsMany()) + return m_operands.first(); + + /* We use CommonValues::IntegerOne here because it is an arbitrary Expression + * of type xs:integer */ + Expression::Ptr op2(wrapLiteral(CommonValues::IntegerOne, context, this)); + m_adder = ArithmeticExpression::fetchMathematician(m_operands.first(), m_operands.first(), + AtomicMathematician::Add, true, context, this); + m_divider = ArithmeticExpression::fetchMathematician(m_operands.first(), op2, + AtomicMathematician::Div, true, context, this); + return me; +} + +SequenceType::Ptr AvgFN::staticType() const +{ + const SequenceType::Ptr opt(m_operands.first()->staticType()); + ItemType::Ptr t(opt->itemType()); + + if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t)) + t = BuiltinTypes::xsDouble; /* xsUntypedAtomics are converted to xsDouble. */ + else if(BuiltinTypes::xsInteger->xdtTypeMatches(t)) + t = BuiltinTypes::xsDecimal; + + /* else, it means the type is xsDayTimeDuration, xsYearMonthDuration, + * xsDouble, xsFloat or xsAnyAtomicType, which we use as is. */ + return makeGenericSequenceType(BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t) ? t : ItemType::Ptr(BuiltinTypes::xsAnyAtomicType), + opt->cardinality().toWithoutMany()); +} + +Item SumFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context)); + Item sum(it->next()); + + while(sum) + { + const Item next(it->next()); + if(!next) + break; + + sum = ArithmeticExpression::flexiblyCalculate(sum, AtomicMathematician::Add, + next, m_mather, context, this, + ReportContext::FORG0006); + }; + + if(!sum) + { + if(m_operands.count() == 1) + return CommonValues::IntegerZero; + else + return m_operands.last()->evaluateSingleton(context); + } + + return sum; +} + +Expression::Ptr SumFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + const Expression::Ptr me(AddingAggregate::typeCheck(context, reqType)); + + if(*CommonSequenceTypes::Empty == *m_operands.first()->staticType()->itemType()) + { + if(m_operands.count() == 1) + return wrapLiteral(CommonValues::IntegerZero, context, this); + else + return m_operands.at(1); + } + + if(m_operands.count() == 1) + return me; + + const ItemType::Ptr t(m_operands.at(1)->staticType()->itemType()); + + if(!BuiltinTypes::numeric->xdtTypeMatches(t) && + !BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t) && + *CommonSequenceTypes::Empty != *t && + !BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t) && + !BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t)) + { + context->error(QtXmlPatterns::tr("The second argument to %1 cannot be " + "of type %2. It must be of type %3, " + "%4, or %5.") + .arg(formatFunction(context->namePool(), signature())) + .arg(formatType(context->namePool(), m_operands.at(1)->staticType())) + .arg(formatType(context->namePool(), BuiltinTypes::numeric)) + .arg(formatType(context->namePool(), BuiltinTypes::xsYearMonthDuration)) + .arg(formatType(context->namePool(), BuiltinTypes::xsDayTimeDuration)), + ReportContext::FORG0006, this); + return me; + } + + return me; +} + +SequenceType::Ptr SumFN::staticType() const +{ + const SequenceType::Ptr t(m_operands.first()->staticType()); + + if(m_operands.count() == 1) + { + return makeGenericSequenceType(t->itemType() | BuiltinTypes::xsInteger, + Cardinality::exactlyOne()); + } + else + { + return makeGenericSequenceType(t->itemType() | m_operands.at(1)->staticType()->itemType(), + t->cardinality().toWithoutMany()); + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qaggregatefns_p.h b/src/xmlpatterns/functions/qaggregatefns_p.h new file mode 100644 index 0000000..9e4eb94 --- /dev/null +++ b/src/xmlpatterns/functions/qaggregatefns_p.h @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AggregateFNs_H +#define Patternist_AggregateFNs_H + +#include "qaggregator_p.h" +#include "qatomiccomparator_p.h" +#include "qatomicmathematician_p.h" +#include "qcomparisonplatform_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#aggregate-functions">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 15.4 Aggregate Functions</a>. + * + * @todo document that some functions have both eval funcs implented. + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function <tt>fn:count()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class CountFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + /** + * If @p reqType is CommonSequenceTypes::EBV, this function call is rewritten + * into a call to <tt>fn:exists()</tt>. Hence, <tt>if(count(X)) then ...</tt> is + * rewritten into <tt>if(exists(X)) then ...</tt>. + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + /** + * If CountFN's operand has a Cardinality that is exact, as per Cardinality::isExact(), + * it is rewritten to the Cardinality's count. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + }; + + /** + * @short Base class for the implementations of the <tt>fn:avg()</tt> and <tt>fn:sum()</tt> function. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class AddingAggregate : public FunctionCall + { + public: + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + protected: + AtomicMathematician::Ptr m_mather; + }; + + /** + * @short Implements the function <tt>fn:avg()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class AvgFN : public AddingAggregate + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + virtual SequenceType::Ptr staticType() const; + private: + AtomicMathematician::Ptr m_adder; + AtomicMathematician::Ptr m_divider; + }; + + /** + * @short Implements the function <tt>fn:sum()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class SumFN : public AddingAggregate + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + virtual SequenceType::Ptr staticType() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qaggregator.cpp b/src/xmlpatterns/functions/qaggregator.cpp new file mode 100644 index 0000000..b585e77 --- /dev/null +++ b/src/xmlpatterns/functions/qaggregator.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qgenericsequencetype_p.h" + +#include "qaggregator_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +SequenceType::Ptr Aggregator::staticType() const +{ + const SequenceType::Ptr t(m_operands.first()->staticType()); + ItemType::Ptr itemType(t->itemType()); + + /* Since we have types that are derived from xs:integer, this ensures that + * the static type is xs:integer even if the argument is for + * instance xs:unsignedShort. */ + if(BuiltinTypes::xsInteger->xdtTypeMatches(itemType) && + !itemType->xdtTypeMatches(BuiltinTypes::xsInteger)) + { + itemType = BuiltinTypes::xsInteger; + } + + return makeGenericSequenceType(itemType, + t->cardinality().toWithoutMany()); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qaggregator_p.h b/src/xmlpatterns/functions/qaggregator_p.h new file mode 100644 index 0000000..7b7e90b --- /dev/null +++ b/src/xmlpatterns/functions/qaggregator_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Aggregator_H +#define Patternist_Aggregator_H + +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Carries a staticType() implementation appropriate + * for functions which returns a singleton value derived from its first argument. + * + * One example of such a function is FloorFN, implementing <tt>fn:floor()</tt>, + * which returns a single value of the same type as the first argument, or the empty + * sequence if the first argument evaluates to the empty sequence. + * + * Aggregator is abstract, and exists for saving code. It is inherited + * by classes which needs the staticType() implementation this class provides. + * + * @see Piper + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class Aggregator : public FunctionCall + { + public: + /** + * @returns a static type where the ItemType is the same as this FunctionCall's first + * argument, and the Cardinality is as return from Cardinality::toWithoutMany(). + */ + virtual SequenceType::Ptr staticType() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qassemblestringfns.cpp b/src/xmlpatterns/functions/qassemblestringfns.cpp new file mode 100644 index 0000000..513ba67 --- /dev/null +++ b/src/xmlpatterns/functions/qassemblestringfns.cpp @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonvalues_p.h" +#include "qpatternistlocale_p.h" +#include "qschemanumeric_p.h" +#include "qatomicstring_p.h" +#include "qtocodepointsiterator_p.h" + +#include "qassemblestringfns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +/* + * Determines whether @p cp is a valid XML 1.0 character. + * + * @see <a href="http://www.w3.org/TR/REC-xml/#charsets">Extensible Markup + * Language (XML) 1.0 (Third Edition)2.2 Characters</a> + */ +static inline bool isValidXML10Char(const qint32 cp) +{ + /* [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | + * [#xE000-#xFFFD] | [#x10000-#x10FFFF] + */ + return (cp == 0x9 || + cp == 0xA || + cp == 0xD || + (0x20 <= cp && cp <= 0xD7FF) || + (0xE000 <= cp && cp <= 0xFFFD) || + (0x10000 <= cp && cp <= 0x10FFFF)); +} + +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::Iterator::Ptr StringToCodepointsFN::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const Item item(m_operands.first()->evaluateSingleton(context)); + if(!item) + return CommonValues::emptyIterator; + + const QString str(item.stringValue()); + if(str.isEmpty()) + return CommonValues::emptyIterator; + else + return Item::Iterator::Ptr(new ToCodepointsIterator(str)); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qassemblestringfns_p.h b/src/xmlpatterns/functions/qassemblestringfns_p.h new file mode 100644 index 0000000..832e283 --- /dev/null +++ b/src/xmlpatterns/functions/qassemblestringfns_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AssembleStringFNs_H +#define Patternist_AssembleStringFNs_H + +#include "qfunctioncall_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#func-assemble-disassemble-string">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 7.2 Functions to Assemble and Disassemble Strings</a>. + * <a href="http://www.azillionmonkeys.com/qed/unicode.html">Quick Guide to understanding + * Unicode Data Transfer Formats</a> + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function <tt>fn:codepoints-to-string()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class CodepointsToStringFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:string-to-codepoints()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class StringToCodepointsFN : public FunctionCall + { + public: + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qbooleanfns.cpp b/src/xmlpatterns/functions/qbooleanfns.cpp new file mode 100644 index 0000000..c20b0e3 --- /dev/null +++ b/src/xmlpatterns/functions/qbooleanfns.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qoptimizationpasses_p.h" + +#include "qbooleanfns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +bool TrueFN::evaluateEBV(const DynamicContext::Ptr &) const +{ + return true; +} + +bool FalseFN::evaluateEBV(const DynamicContext::Ptr &) const +{ + return false; +} + +bool NotFN::evaluateEBV(const DynamicContext::Ptr &context) const +{ + /* That little '!' is quite important in this function -- I forgot it ;-) */ + return !m_operands.first()->evaluateEBV(context); +} + +OptimizationPass::List NotFN::optimizationPasses() const +{ + return OptimizationPasses::notFN; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qbooleanfns_p.h b/src/xmlpatterns/functions/qbooleanfns_p.h new file mode 100644 index 0000000..9890981 --- /dev/null +++ b/src/xmlpatterns/functions/qbooleanfns_p.h @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_BooleanFNs_H +#define Patternist_BooleanFNs_H + +#include "qfunctioncall_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#boolean-functions">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 9 Functions and Operators on Boolean Values</a>. + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements the function <tt>fn:true()</tt>. + * + * The implementation always rewrites itself to a boolean value at compile time. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class TrueFN : public FunctionCall + { + public: + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:false()</tt>. + * + * The implementation always rewrites itself to a boolean value at compile time. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class FalseFN : public FunctionCall + { + public: + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:not()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class NotFN : public FunctionCall + { + public: + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + virtual QList<QExplicitlySharedDataPointer<OptimizationPass> > optimizationPasses() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qcomparescaseaware.cpp b/src/xmlpatterns/functions/qcomparescaseaware.cpp new file mode 100644 index 0000000..2fee0f7 --- /dev/null +++ b/src/xmlpatterns/functions/qcomparescaseaware.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qvaluecomparison_p.h" + +#include "qcomparescaseaware_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ComparesCaseAware::ComparesCaseAware() : m_caseSensitivity(Qt::CaseSensitive) +{ +} + +Expression::Ptr ComparesCaseAware::compress(const StaticContext::Ptr &context) +{ + Q_ASSERT(m_operands.size() >= 2); + + if(ValueComparison::isCaseInsensitiveCompare(m_operands.first(), m_operands[1])) + m_caseSensitivity = Qt::CaseInsensitive; + else + { + /* Yes, we could probably skip this since m_caseSensitivity is initialized to this value, + * but perhaps subsequent calls to compress() can make isCaseInsensitiveCompare() return + * a different value. */ + m_caseSensitivity = Qt::CaseSensitive; + } + + return FunctionCall::compress(context); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qcomparescaseaware_p.h b/src/xmlpatterns/functions/qcomparescaseaware_p.h new file mode 100644 index 0000000..7791949 --- /dev/null +++ b/src/xmlpatterns/functions/qcomparescaseaware_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ComparesCaseAware_H +#define Patternist_ComparesCaseAware_H + +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base-class for functions that compares strings and provides + * an opportunity to optimize compares intended to be case insensitive. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class ComparesCaseAware : public FunctionCall + { + public: + /** + * Performs initialization. + */ + ComparesCaseAware(); + + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + /** + * Tells whether the return value of the two operands must be compared + * case insensitively or not. + */ + inline Qt::CaseSensitivity caseSensitivity() const + { + return m_caseSensitivity; + } + + private: + Qt::CaseSensitivity m_caseSensitivity; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qcomparestringfns.cpp b/src/xmlpatterns/functions/qcomparestringfns.cpp new file mode 100644 index 0000000..1f2fcee6 --- /dev/null +++ b/src/xmlpatterns/functions/qcomparestringfns.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonnamespaces_p.h" + +#include "qboolean_p.h" +#include "qcommonvalues_p.h" +#include "qinteger_p.h" +#include "qatomicstring_p.h" + +#include "qcomparestringfns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item CodepointEqualFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item op1(m_operands.first()->evaluateSingleton(context)); + if(!op1) + return Item(); + + const Item op2(m_operands.last()->evaluateSingleton(context)); + if(!op2) + return Item(); + + if(caseSensitivity() == Qt::CaseSensitive) + return Boolean::fromValue(op1.stringValue() == op2.stringValue()); + else + { + const QString s1(op1.stringValue()); + const QString s2(op2.stringValue()); + + return Boolean::fromValue(s1.length() == s2.length() && + s1.startsWith(s2, Qt::CaseInsensitive)); + } +} + +Item CompareFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item op1(m_operands.first()->evaluateSingleton(context)); + if(!op1) + return Item(); + + const Item op2(m_operands.at(1)->evaluateSingleton(context)); + if(!op2) + return Item(); + + const int retval = caseSensitivity() == Qt::CaseSensitive + ? op1.stringValue().compare(op2.stringValue()) + : op1.stringValue().toLower().compare(op2.stringValue().toLower()); + + if(retval > 0) + return CommonValues::IntegerOne; + else if(retval < 0) + return CommonValues::IntegerOneNegative; + else + { + Q_ASSERT(retval == 0); + return CommonValues::IntegerZero; + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qcomparestringfns_p.h b/src/xmlpatterns/functions/qcomparestringfns_p.h new file mode 100644 index 0000000..11ebd2a --- /dev/null +++ b/src/xmlpatterns/functions/qcomparestringfns_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CompareStringFNs_H +#define Patternist_CompareStringFNs_H + +#include "qcomparescaseaware_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#string-compare">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 7.3 Equality and Comparison of Strings</a>. + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements the function <tt>fn:codepoint-equal()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class CodepointEqualFN : public ComparesCaseAware + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:compare()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class CompareFN : public ComparesCaseAware + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qcomparingaggregator.cpp b/src/xmlpatterns/functions/qcomparingaggregator.cpp new file mode 100644 index 0000000..a87e659 --- /dev/null +++ b/src/xmlpatterns/functions/qcomparingaggregator.cpp @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/** + * @file qcomparingaggregator.cpp + * @short This file is included by qcomparingaggregator_p.h. + * If you need includes in this file, put them in qcomparingaggregator_p.h, outside of the namespace. + */ + +template <AtomicComparator::Operator oper, AtomicComparator::ComparisonResult result> +inline Item +ComparingAggregator<oper, result>::applyNumericPromotion(const Item &old, + const Item &nev, + const Item &newVal) const +{ + Q_ASSERT(old); + Q_ASSERT(nev); + Q_ASSERT(newVal); + const ItemType::Ptr to(old.type()); + const ItemType::Ptr tn(nev.type()); + + if(!(BuiltinTypes::numeric->xdtTypeMatches(to) && BuiltinTypes::numeric->xdtTypeMatches(tn))) + return newVal; /* At least one of them isn't numeric. */ + else if(BuiltinTypes::xsDouble->xdtTypeMatches(to) || BuiltinTypes::xsDouble->xdtTypeMatches(tn)) + return toItem(Double::fromValue(newVal.as<Numeric>()->toDouble())); + else if(BuiltinTypes::xsFloat->xdtTypeMatches(to) || BuiltinTypes::xsFloat->xdtTypeMatches(tn)) + return toItem(Float::fromValue(newVal.as<Numeric>()->toDouble())); + else if(BuiltinTypes::xsInteger->xdtTypeMatches(to) && + BuiltinTypes::xsInteger->xdtTypeMatches(tn)) + return newVal; /* Both must be xs:integer. */ + else + return toItem(Decimal::fromValue(newVal.as<Numeric>()->toDecimal())); +} + +template <AtomicComparator::Operator oper, AtomicComparator::ComparisonResult result> +Item +ComparingAggregator<oper, result>::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context)); + Item largest; + + while(true) + { + Item next(it->next()); + + if(!next) + { + return largest; + } + + AtomicComparator::Ptr comp(comparator()); + + if(!comp) + { + ItemType::Ptr t1(next.type()); + Q_ASSERT(t1); + + if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1)) + { + next = cast(next, context); + t1 = BuiltinTypes::xsDouble; + } + + if(!largest) + { + largest = next; + continue; + } + + Q_ASSERT(largest); + comp = fetchComparator(largest.type(), t1, context); + Q_ASSERT(comp); + } + else if(!largest) + { + largest = next; + continue; + } + + if(comp->compare(next, operatorID(), largest) == result) + { + largest = applyNumericPromotion(largest, next, next); + continue; + } + + const ItemType::Ptr t(next.type()); + + if(BuiltinTypes::xsDouble->xdtTypeMatches(t) && + next.as<Numeric>()->isNaN()) + { + return CommonValues::DoubleNaN; + } + else if(BuiltinTypes::xsFloat->xdtTypeMatches(t) && + next.as<Numeric>()->isNaN()) + { + if(BuiltinTypes::xsDouble->xdtTypeMatches(largest.type())) + return CommonValues::DoubleNaN; + + /* If we have a xs:double somewhere, we must promote the NaN value to xs:double, + * and we really should raise error on invalid value. */ + largest = it->next(); + + while(largest) + { + const ItemType::Ptr tf(largest.type()); + if(BuiltinTypes::xsDouble->xdtTypeMatches(tf)) + return CommonValues::DoubleNaN; + else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(tf)) + { + /* Attempt a convert, which will raise an error if it doesn't work out. */ + cast(largest, context); + return CommonValues::DoubleNaN; + } + else if(!BuiltinTypes::numeric->xdtTypeMatches(tf)) + { + fetchComparator(BuiltinTypes::xsFloat, tf, context); + } + else + largest = it->next(); + }; + + return CommonValues::FloatNaN; + } + else + largest = applyNumericPromotion(largest, next, largest); + } +} + +template <AtomicComparator::Operator oper, AtomicComparator::ComparisonResult result> +Expression::Ptr +ComparingAggregator<oper, result>::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + Q_ASSERT(oper == AtomicComparator::OperatorGreaterThan || + oper == AtomicComparator::OperatorLessThan); + const Expression::Ptr me(FunctionCall::typeCheck(context, reqType)); + + ItemType::Ptr t1(m_operands.first()->staticType()->itemType()); + + if(*CommonSequenceTypes::Empty == *t1) + return EmptySequence::create(this, context); + else if(*BuiltinTypes::xsAnyAtomicType == *t1 || + BuiltinTypes::numeric->xdtTypeMatches(t1)) + return me; + else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1)) + { + m_operands.replace(0, Expression::Ptr(new UntypedAtomicConverter(m_operands.first(), + BuiltinTypes::xsDouble))); + t1 = m_operands.first()->staticType()->itemType(); + } + else if(!BuiltinTypes::xsString->xdtTypeMatches(t1) && + !BuiltinTypes::xsAnyURI->xdtTypeMatches(t1) && + !BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t1) && + !BuiltinTypes::xsDate->xdtTypeMatches(t1) && + !BuiltinTypes::xsTime->xdtTypeMatches(t1) && + !BuiltinTypes::xsDateTime->xdtTypeMatches(t1) && + !BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t1)) + { + context->error(QtXmlPatterns::tr("The first argument to %1 cannot be of type %2.") + .arg(formatFunction(context->namePool(), signature())) + .arg(formatType(context->namePool(), m_operands.first()->staticType())), + ReportContext::FORG0006, this); + return me; + } + + if(!m_operands.first()->staticType()->cardinality().allowsMany()) + return m_operands.first(); + + prepareComparison(fetchComparator(t1, t1, context)); + + return me; +} + diff --git a/src/xmlpatterns/functions/qcomparingaggregator_p.h b/src/xmlpatterns/functions/qcomparingaggregator_p.h new file mode 100644 index 0000000..374fa7a --- /dev/null +++ b/src/xmlpatterns/functions/qcomparingaggregator_p.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ComparingAggregator_H +#define Patternist_ComparingAggregator_H + +/** + * @file qcomparingaggregator_p.h + * @short Contains the implementations for the functions <tt>fn:max()</tt>, MaxFN, + * and <tt>fn:min()</tt>, MinFN, and the class ComparingAggregator. + */ + +#include "qabstractfloat_p.h" +#include "qdecimal_p.h" +#include "qcastingplatform_p.h" +#include "qcomparisonplatform_p.h" +#include "qliteral_p.h" +#include "qaggregator_p.h" +#include "quntypedatomicconverter_p.h" +#include "qpatternistlocale_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for the implementations of the <tt>fn:min()</tt> and <tt>fn:max()</tt> function. + * + * What function that more specifically is + * followed, depends on how the constructor is called. + * + * @see MaxFN + * @see MinFN + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + template <AtomicComparator::Operator oper, AtomicComparator::ComparisonResult result> + class ComparingAggregator : public Aggregator, + public ComparisonPlatform<ComparingAggregator<oper, result>, + true, AtomicComparator::AsValueComparison, + ReportContext::FORG0006>, + public CastingPlatform<ComparingAggregator<oper, result>, true> + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + inline AtomicComparator::Operator operatorID() const + { + return oper; + } + + inline ItemType::Ptr targetType() const + { + return BuiltinTypes::xsDouble; + } + + private: + inline Item applyNumericPromotion(const Item &old, + const Item &nev, + const Item &newVal) const; + + using ComparisonPlatform<ComparingAggregator<oper, result>, + true, + AtomicComparator::AsValueComparison, + ReportContext::FORG0006>::comparator; + using ComparisonPlatform<ComparingAggregator<oper, result>, + true, + AtomicComparator::AsValueComparison, + ReportContext::FORG0006>::fetchComparator; + using CastingPlatform<ComparingAggregator<oper, result>, true>::cast; + }; + +#include "qcomparingaggregator.cpp" + + /** + * @short An instantiation of ComparingAggregator suitable for <tt>fn:max()</tt>. + * + * @ingroup Patternist_functions + */ + typedef ComparingAggregator<AtomicComparator::OperatorGreaterThan, AtomicComparator::GreaterThan> MaxFN; + + /** + * @short An instantiation of ComparingAggregator suitable for <tt>fn:max()</tt>. + * + * @ingroup Patternist_functions + */ + typedef ComparingAggregator<AtomicComparator::OperatorLessThan, AtomicComparator::LessThan> MinFN; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qconstructorfunctionsfactory.cpp b/src/xmlpatterns/functions/qconstructorfunctionsfactory.cpp new file mode 100644 index 0000000..529cab9 --- /dev/null +++ b/src/xmlpatterns/functions/qconstructorfunctionsfactory.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qatomictype_p.h" +#include "qbuiltintypes_p.h" +#include "qcastas_p.h" +#include "qcommonnamespaces_p.h" +#include "qcommonsequencetypes_p.h" +#include "qfunctionargument_p.h" +#include "qfunctioncall_p.h" +#include "qgenericsequencetype_p.h" +#include "qschematype_p.h" +#include "qschematypefactory_p.h" + +#include "qconstructorfunctionsfactory_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ConstructorFunctionsFactory::ConstructorFunctionsFactory(const NamePool::Ptr &np, const SchemaTypeFactory::Ptr &f) : m_typeFactory(f) +{ + Q_ASSERT(m_typeFactory); + Q_ASSERT(np); + SchemaType::Hash::const_iterator it(m_typeFactory->types().constBegin()); + const SchemaType::Hash::const_iterator end(m_typeFactory->types().constEnd()); + + FunctionArgument::List args; + const QXmlName argName(StandardNamespaces::empty, StandardLocalNames::sourceValue); + + args.append(FunctionArgument::Ptr(new FunctionArgument(argName, + CommonSequenceTypes::ZeroOrOneAtomicType))); + + while(it != end) + { + if(!BuiltinTypes::xsAnyAtomicType->wxsTypeMatches(*it) || + *BuiltinTypes::xsAnyAtomicType == *static_cast<const AtomicType *>((*it).data()) || + *BuiltinTypes::xsNOTATION == *static_cast<const AtomicType *>((*it).data())) + { + /* It's not a valid type for a constructor function -- skip it. */ + ++it; + continue; + } + + const QXmlName name((*it)->name(np)); + FunctionSignature::Ptr s(new FunctionSignature(name, 1, 1, + makeGenericSequenceType(AtomicType::Ptr(*it), + Cardinality::zeroOrOne()))); + s->setArguments(args); + m_signatures.insert(name, s); + ++it; + } +} + +Expression::Ptr ConstructorFunctionsFactory::retrieveExpression(const QXmlName name, + const Expression::List &args, + const FunctionSignature::Ptr &sign) const +{ + Q_UNUSED(sign); + + /* This function is only called if the callsite is valid, so createSchemaType() will always + * return an AtomicType. */ + const AtomicType::Ptr at(static_cast<AtomicType *>(m_typeFactory->createSchemaType(name).data())); + + return Expression::Ptr(new CastAs(args.first(), + makeGenericSequenceType(at, + Cardinality::zeroOrOne()))); +} + +FunctionSignature::Ptr ConstructorFunctionsFactory::retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name) +{ + Q_UNUSED(np); + return functionSignatures().value(name); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qconstructorfunctionsfactory_p.h b/src/xmlpatterns/functions/qconstructorfunctionsfactory_p.h new file mode 100644 index 0000000..9861f7c --- /dev/null +++ b/src/xmlpatterns/functions/qconstructorfunctionsfactory_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ConstructorFunctionsFactory_H +#define Patternist_ConstructorFunctionsFactory_H + +#include "qabstractfunctionfactory_p.h" +#include "qschematypefactory_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short A function factory that handles the builtin constructor functions, such + * as <tt>xs:time()</tt>. + * + * @see <a href="http://www.w3.org/TR/xpath20/#id-constructor-functions">XML Path + * Language (XPath) 2.0, 3.10.4 Constructor Functions</a> + * @author Frans Englich <fenglich@trolltech.com> + * @ingroup Patternist_functions + */ + class ConstructorFunctionsFactory : public AbstractFunctionFactory + { + public: + ConstructorFunctionsFactory(const NamePool::Ptr &np, const SchemaTypeFactory::Ptr &); + + virtual FunctionSignature::Ptr retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name); + + protected: + virtual Expression::Ptr retrieveExpression(const QXmlName name, + const Expression::List &args, + const FunctionSignature::Ptr &sign) const; + + private: + const SchemaTypeFactory::Ptr m_typeFactory; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qcontextfns.cpp b/src/xmlpatterns/functions/qcontextfns.cpp new file mode 100644 index 0000000..89da9db --- /dev/null +++ b/src/xmlpatterns/functions/qcontextfns.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qanyuri_p.h" +#include "qdate_p.h" +#include "qschemadatetime_p.h" +#include "qdaytimeduration_p.h" +#include "qinteger_p.h" +#include "qliteral_p.h" +#include "qatomicstring_p.h" +#include "qschematime_p.h" + +#include "qcontextfns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item PositionFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + Q_ASSERT(context); + return Integer::fromValue(context->contextPosition()); +} + +Item LastFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + Q_ASSERT(context); + return Integer::fromValue(context->contextSize()); +} + +Item ImplicitTimezoneFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return toItem(context->implicitTimezone()); +} + +Item CurrentDateTimeFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return toItem(DateTime::fromDateTime(context->currentDateTime())); +} + +Item CurrentDateFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return toItem(Date::fromDateTime(context->currentDateTime())); +} + +Item CurrentTimeFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return toItem(SchemaTime::fromDateTime(context->currentDateTime())); +} + +Expression::Ptr StaticBaseURIFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + /* Our base URI can never be undefined. */ + return wrapLiteral(toItem(AnyURI::fromValue(context->baseURI())), context, this)->typeCheck(context, reqType); +} + +Expression::Ptr DefaultCollationFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + return wrapLiteral(AtomicString::fromValue(context->defaultCollation().toString()), context, this)->typeCheck(context, reqType); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qcontextfns_p.h b/src/xmlpatterns/functions/qcontextfns_p.h new file mode 100644 index 0000000..08698e7 --- /dev/null +++ b/src/xmlpatterns/functions/qcontextfns_p.h @@ -0,0 +1,195 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ContextFNs_H +#define Patternist_ContextFNs_H + +#include "qfunctioncall_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#context">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 16 Context Functions</a>. + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function <tt>fn:position()</tt>. + * + * @see <a href="http://www.w3.org/TR/xpath-functions/#func-position">XQuery 1.0 + * and XPath 2.0 Functions and Operators, 16.1 fn:position</a> + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class PositionFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:last()</tt>. + * + * @see <a href="http://www.w3.org/TR/xpath-functions/#func-last">XQuery 1.0 + * and XPath 2.0 Functions and Operators, 16.2 fn:last</a> + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class LastFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:implicit-timezone()</tt>. + * + * @see <a href="http://www.w3.org/TR/xpath-functions/#func-implicit-timezone">XQuery 1.0 + * and XPath 2.0 Functions and Operators, 16.6 fn:implicit-timezone</a> + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class ImplicitTimezoneFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:current-dateTime()</tt>. + * + * @see <a href="http://www.w3.org/TR/xpath-functions/#func-current-dateTime">XQuery 1.0 + * and XPath 2.0 Functions and Operators, 16.3 fn:current-dateTime</a> + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class CurrentDateTimeFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:current-date()</tt>. + * + * @see <a href="http://www.w3.org/TR/xpath-functions/#func-current-date">XQuery 1.0 + * and XPath 2.0 Functions and Operators, 16.4 fn:current-date</a> + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class CurrentDateFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:current-time()</tt>. + * + * @see <a href="http://www.w3.org/TR/xpath-functions/#func-current-time">XQuery 1.0 + * and XPath 2.0 Functions and Operators, 16.5 fn:current-date</a> + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class CurrentTimeFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:default-collation()</tt>. + * + * This is done by rewriting to StaticContext::defaultCollation() at the typeCheck() stage. + * + * @see <a href="http://www.w3.org/TR/xpath-functions/#func-default-collation">XQuery 1.0 + * and XPath 2.0 Functions and Operators, 16.7 fn:default-collation</a> + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class DefaultCollationFN : public FunctionCall + { + public: + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + }; + + /** + * @short Implements the function <tt>fn:static-base-uri()</tt>. + * + * This is done by rewriting to StaticContext::baseURI() at the typeCheck() stage. + * + * @see <a href="http://www.w3.org/TR/xpath-functions/#func-static-base-uri">XQuery 1.0 + * and XPath 2.0 Functions and Operators, 16.8 fn:static-base-uri</a> + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class StaticBaseURIFN : public FunctionCall + { + public: + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qcontextnodechecker.cpp b/src/xmlpatterns/functions/qcontextnodechecker.cpp new file mode 100644 index 0000000..2d1df49 --- /dev/null +++ b/src/xmlpatterns/functions/qcontextnodechecker.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcontextnodechecker_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +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); + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qcontextnodechecker_p.h b/src/xmlpatterns/functions/qcontextnodechecker_p.h new file mode 100644 index 0000000..5745bc4 --- /dev/null +++ b/src/xmlpatterns/functions/qcontextnodechecker_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ContextNodeChecker_H +#define Patternist_ContextNodeChecker_H + +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Helper class that checks that the context node is a document + * node. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class ContextNodeChecker : public FunctionCall + { + protected: + /** + * @short Checks that the root node of @p node is a document node, and + * otherwise issues an error. + */ + void checkTargetNode(const QXmlNodeModelIndex &node, + const DynamicContext::Ptr &context, + const ReportContext::ErrorCode) const; + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qcurrentfn.cpp b/src/xmlpatterns/functions/qcurrentfn.cpp new file mode 100644 index 0000000..f4ae778 --- /dev/null +++ b/src/xmlpatterns/functions/qcurrentfn.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qcurrentfn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item CurrentFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return context->currentItem(); +} + +Expression::Ptr CurrentFN::compress(const StaticContext::Ptr &context) +{ + m_itemType = context->currentItemType(); + return FunctionCall::compress(context); +} + +Expression::Ptr CurrentFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + m_itemType = context->currentItemType(); + return FunctionCall::typeCheck(context, reqType); +} + +SequenceType::Ptr CurrentFN::staticType() const +{ + if(m_itemType) + return makeGenericSequenceType(m_itemType, Cardinality::exactlyOne()); + else + return CommonSequenceTypes::ExactlyOneItem; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qcurrentfn_p.h b/src/xmlpatterns/functions/qcurrentfn_p.h new file mode 100644 index 0000000..cc9d295 --- /dev/null +++ b/src/xmlpatterns/functions/qcurrentfn_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CurrentFN_H +#define Patternist_CurrentFN_H + +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements XSL-T's function <tt>fn:current()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + * @since 4.5 + */ + class CurrentFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + virtual SequenceType::Ptr staticType() const; + + private: + ItemType::Ptr m_itemType; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qdatetimefn.cpp b/src/xmlpatterns/functions/qdatetimefn.cpp new file mode 100644 index 0000000..5727794 --- /dev/null +++ b/src/xmlpatterns/functions/qdatetimefn.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qatomiccomparator_p.h" +#include "qcommonvalues_p.h" +#include "qschemadatetime_p.h" +#include "qdaytimeduration_p.h" +#include "qdecimal_p.h" +#include "qinteger_p.h" +#include "qpatternistlocale_p.h" + +#include "qdatetimefn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item DateTimeFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item di(m_operands.first()->evaluateSingleton(context)); + if(!di) + return Item(); + + const Item ti(m_operands.last()->evaluateSingleton(context)); + if(!ti) + return Item(); + + QDateTime date(di.as<AbstractDateTime>()->toDateTime()); + Q_ASSERT(date.isValid()); + QDateTime time(ti.as<AbstractDateTime>()->toDateTime()); + Q_ASSERT(time.isValid()); + + if(date.timeSpec() == time.timeSpec() || /* Identical timezone properties. */ + time.timeSpec() == Qt::LocalTime) /* time has no timezone, but date do. */ + { + date.setTime(time.time()); + Q_ASSERT(date.isValid()); + return DateTime::fromDateTime(date); + } + else if(date.timeSpec() == Qt::LocalTime) /* date has no timezone, but time do. */ + { + time.setDate(date.date()); + Q_ASSERT(time.isValid()); + return DateTime::fromDateTime(time); + } + else + { + context->error(QtXmlPatterns::tr("If both values have zone offsets, " + "they must have the same zone offset. " + "%1 and %2 are not the same.") + .arg(formatData(di.stringValue()), + formatData(di.stringValue())), + ReportContext::FORG0008, this); + return Item(); /* Silence GCC warning. */ + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qdatetimefn_p.h b/src/xmlpatterns/functions/qdatetimefn_p.h new file mode 100644 index 0000000..69567d2 --- /dev/null +++ b/src/xmlpatterns/functions/qdatetimefn_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DateTimeFN_H +#define Patternist_DateTimeFN_H + +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function <tt>fn:dateTime()</tt>. + * + * @see <a href="http://www.w3.org/TR/xpath-functions/#func-dateTime">XQuery 1.0 + * and XPath 2.0 Functions and Operators, 5.2 A Special Constructor Function for xs:dateTime</a> + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class DateTimeFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qdatetimefns.cpp b/src/xmlpatterns/functions/qdatetimefns.cpp new file mode 100644 index 0000000..756504b --- /dev/null +++ b/src/xmlpatterns/functions/qdatetimefns.cpp @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/** + * @file + * @short This file is included by qdatetimefns_p.h. + * If you need includes in this file, put them in qdatetimefns_p.h, outside of the namespace. + */ + +template<typename TSubClass> +Item ExtractFromDurationFN<TSubClass>::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item item(m_operands.first()->evaluateSingleton(context)); + if(item) + { + return static_cast<const TSubClass *>(this)-> + extract(item.as<AbstractDuration>()); + } + else + return Item(); +} + +Item YearsFromDurationFN::extract(const AbstractDuration *const duration) const +{ + return Integer::fromValue(duration->years() * (duration->isPositive() ? 1 : -1)); +} + +Item MonthsFromDurationFN::extract(const AbstractDuration *const duration) const +{ + return Integer::fromValue(duration->months() * (duration->isPositive() ? 1 : -1)); +} + +Item DaysFromDurationFN::extract(const AbstractDuration *const duration) const +{ + return Integer::fromValue(duration->days() * (duration->isPositive() ? 1 : -1)); +} + +Item HoursFromDurationFN::extract(const AbstractDuration *const duration) const +{ + return Integer::fromValue(duration->hours() * (duration->isPositive() ? 1 : -1)); +} + +Item MinutesFromDurationFN::extract(const AbstractDuration *const duration) const +{ + return Integer::fromValue(duration->minutes() * (duration->isPositive() ? 1 : -1)); +} + +Item SecondsFromDurationFN::extract(const AbstractDuration *const duration) const +{ + return toItem(Decimal::fromValue((duration->seconds() + duration->mseconds() / 1000.0) * + (duration->isPositive() ? 1 : -1))); +} + +template<typename TSubClass> +Item ExtractFromDateTimeFN<TSubClass>::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item item(m_operands.first()->evaluateSingleton(context)); + if(item) + { + return static_cast<const TSubClass *>(this)-> + extract(item.as<AbstractDateTime>()->toDateTime()); + } + else + return Item(); +} + +Item YearFromAbstractDateTimeFN::extract(const QDateTime &dt) const +{ + return Integer::fromValue(dt.date().year()); +} + +Item DayFromAbstractDateTimeFN::extract(const QDateTime &dt) const +{ + return Integer::fromValue(dt.date().day()); +} + +Item MinutesFromAbstractDateTimeFN::extract(const QDateTime &dt) const +{ + return Integer::fromValue(dt.time().minute()); +} + +Item SecondsFromAbstractDateTimeFN::extract(const QDateTime &dt) const +{ + const QTime time(dt.time()); + return toItem(Decimal::fromValue(time.second() + time.msec() / 1000.0)); +} + +Item TimezoneFromAbstractDateTimeFN::extract(const QDateTime &dt) const +{ + if(dt.timeSpec() == Qt::UTC) + return toItem(CommonValues::DayTimeDurationZero); + else if(dt.timeSpec() == Qt::OffsetFromUTC) + return toItem(DayTimeDuration::fromSeconds(dt.utcOffset())); + else + return Item(); +} + +Item MonthFromAbstractDateTimeFN::extract(const QDateTime &dt) const +{ + return Integer::fromValue(dt.date().month()); +} + +Item HoursFromAbstractDateTimeFN::extract(const QDateTime &dt) const +{ + return Integer::fromValue(dt.time().hour()); +} + diff --git a/src/xmlpatterns/functions/qdatetimefns_p.h b/src/xmlpatterns/functions/qdatetimefns_p.h new file mode 100644 index 0000000..0adb3f3 --- /dev/null +++ b/src/xmlpatterns/functions/qdatetimefns_p.h @@ -0,0 +1,305 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DateTimeFNs_H +#define Patternist_DateTimeFNs_H + +#include "qatomiccomparator_p.h" +#include "qcommonvalues_p.h" +#include "qschemadatetime_p.h" +#include "qdaytimeduration_p.h" +#include "qdecimal_p.h" +#include "qinteger_p.h" +#include "qfunctioncall_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#component-exraction-functions">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 10.5 Component Extraction Functions on Durations, Dates and Times</a>. + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Helper class for implementing functions extracting components from durations. + * + * Each sub-class must implement this function: + * + * @code + * Item extract(const AbstractDuration *const duration) const; + * @endcode + * + * This function performs the actual component extraction from the argument, that + * is guaranteed to never be @c null. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + template<typename TSubClass> + class ExtractFromDurationFN : public FunctionCall + { + public: + /** + * Takes care of the argument handling, and, if applicable, + * calls extract() with the value of the operand. + */ + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:years-from-duration()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class YearsFromDurationFN : public ExtractFromDurationFN<YearsFromDurationFN> + { + public: + inline Item extract(const AbstractDuration *const duration) const; + }; + + /** + * @short Implements the function <tt>fn:months-from-duration()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class MonthsFromDurationFN : public ExtractFromDurationFN<MonthsFromDurationFN> + { + public: + inline Item extract(const AbstractDuration *const duration) const; + }; + + /** + * @short Implements the function <tt>fn:days-from-duration()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class DaysFromDurationFN : public ExtractFromDurationFN<DaysFromDurationFN> + { + public: + inline Item extract(const AbstractDuration *const duration) const; + }; + + /** + * @short Implements the function <tt>fn:hours-from-duration()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class HoursFromDurationFN : public ExtractFromDurationFN<HoursFromDurationFN> + { + public: + inline Item extract(const AbstractDuration *const duration) const; + }; + + /** + * @short Implements the function <tt>fn:minutes-from-duration()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class MinutesFromDurationFN : public ExtractFromDurationFN<MinutesFromDurationFN> + { + public: + inline Item extract(const AbstractDuration *const duration) const; + }; + + /** + * @short Implements the function <tt>fn:seconds-from-duration()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class SecondsFromDurationFN : public ExtractFromDurationFN<SecondsFromDurationFN> + { + public: + inline Item extract(const AbstractDuration *const duration) const; + }; + + /** + * @short Helper class for implementing functions extracting components + * from date/time values. + * + * Each sub-class must implement this function: + * + * @code + * Item extract(const AbstractDuration *const duration) const; + * @endcode + * + * This function performs the actual component extraction from the argument, that + * is guaranteed to never be @c null. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + template<typename TSubClass> + class ExtractFromDateTimeFN : public FunctionCall + { + public: + /** + * Takes care of the argument handling, and, if applicable, + * calls extract() with the value of the operand. + */ + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Extracts the year property from a sub-class of AbstractDateTime such as DateTime or Date. + * This function implements <tt>fn:year-from-dateTime()</tt> and <tt>fn:year-from-date()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class YearFromAbstractDateTimeFN : public ExtractFromDateTimeFN<YearFromAbstractDateTimeFN> + { + public: + inline Item extract(const QDateTime &dt) const; + }; + + /** + * @short Extracts the day property from a sub-class of AbstractDateTime such as DateTime or Date. + * This function implements <tt>fn:day-from-dateTime()</tt> and <tt>fn:day-from-date()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class DayFromAbstractDateTimeFN : public ExtractFromDateTimeFN<DayFromAbstractDateTimeFN> + { + public: + inline Item extract(const QDateTime &dt) const; + }; + + /** + * @short Extracts the minute property from a sub-class of AbstractDateTime such as DateTime or SchemaTime. + * Implements the functions <tt>fn:hours-from-dateTime()</tt> and + * <tt>fn:hours-from-time()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class HoursFromAbstractDateTimeFN : public ExtractFromDateTimeFN<HoursFromAbstractDateTimeFN> + { + public: + inline Item extract(const QDateTime &dt) const; + }; + + /** + * @short Extracts the minutes property from a sub-class of AbstractDateTime such as DateTime or Date. + * Implements the functions <tt>fn:minutes-from-dateTime()</tt> and + * <tt>fn:minutes-from-time()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class MinutesFromAbstractDateTimeFN : public ExtractFromDateTimeFN<MinutesFromAbstractDateTimeFN> + { + public: + inline Item extract(const QDateTime &dt) const; + }; + + /** + * @short Extracts the seconds property from a sub-class of AbstractDateTime such as DateTime or Date. + * Implements the functions <tt>fn:seconds-from-dateTime()</tt> and + * <tt>fn:seconds-from-time()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class SecondsFromAbstractDateTimeFN : public ExtractFromDateTimeFN<SecondsFromAbstractDateTimeFN> + { + public: + inline Item extract(const QDateTime &dt) const; + }; + + /** + * @short Extracts the timezone property from a sub-class of AbstractDateTime such as DateTime or Date. + * Implements the functions <tt>fn:timezone-from-dateTime()</tt>, + * <tt>fn:timezone-from-time()</tt> and <tt>fn:timezone-from-date()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class TimezoneFromAbstractDateTimeFN : public ExtractFromDateTimeFN<TimezoneFromAbstractDateTimeFN> + { + public: + inline Item extract(const QDateTime &dt) const; + }; + + /** + * @short implements the functions <tt>fn:month-from-dateTime()</tt> and <tt>fn:month-from-date()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class MonthFromAbstractDateTimeFN : public ExtractFromDateTimeFN<MonthFromAbstractDateTimeFN> + { + public: + inline Item extract(const QDateTime &dt) const; + }; + +#include "qdatetimefns.cpp" + +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qdeepequalfn.cpp b/src/xmlpatterns/functions/qdeepequalfn.cpp new file mode 100644 index 0000000..133ab60 --- /dev/null +++ b/src/xmlpatterns/functions/qdeepequalfn.cpp @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qliteral_p.h" +#include "qschemanumeric_p.h" + +#include "qdeepequalfn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +bool DeepEqualFN::evaluateEBV(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr it1(m_operands.first()->evaluateSequence(context)); + const Item::Iterator::Ptr it2(m_operands.at(1)->evaluateSequence(context)); + + while(true) + { + const Item item1(it1->next()); + const Item item2(it2->next()); + + if(!item1) + { + if(item2) + return false; + else + return true; + } + else if(!item2) + { + if(item1) + return false; + else + return true; + } + else if(item1.isNode()) + { + if(item2.isNode()) + { + if(item1.asNode().isDeepEqual(item2.asNode())) + continue; + else + return false; + } + else + return false; + } + else if(item2.isNode()) + { + /* We know that item1 is not a node due to the check above. */ + return false; + } + else if(flexibleCompare(item1, item2, context)) + continue; + else if(BuiltinTypes::numeric->itemMatches(item1) && + item1.as<Numeric>()->isNaN() && + item2.as<Numeric>()->isNaN()) + { + // TODO + /* Handle the specific NaN circumstances. item2 isn't checked whether it's of + * type numeric, since the AtomicComparator lookup would have failed if both weren't + * numeric. */ + continue; + } + else + return false; + }; +} + +Expression::Ptr DeepEqualFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + const Expression::Ptr me(FunctionCall::typeCheck(context, reqType)); + const ItemType::Ptr t1(m_operands.first()->staticType()->itemType()); + const ItemType::Ptr t2(m_operands.at(1)->staticType()->itemType()); + /* TODO This can be much more improved, and the optimizations should be moved + * to compress(). */ + + if(*CommonSequenceTypes::Empty == *t1) + { + if(*CommonSequenceTypes::Empty == *t2) + return wrapLiteral(CommonValues::BooleanTrue, context, this); + else + return me; + } + else if(*CommonSequenceTypes::Empty == *t2) + { + if(*CommonSequenceTypes::Empty == *t1) + return wrapLiteral(CommonValues::BooleanTrue, context, this); + else + return me; + } + else if(BuiltinTypes::node->xdtTypeMatches(t1) && + BuiltinTypes::node->xdtTypeMatches(t2)) + return me; /* We're comparing nodes. */ + else if(BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t1) && + BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t2)) + { + prepareComparison(fetchComparator(t1, t2, context)); + return me; + } + else + { + if ((BuiltinTypes::node->xdtTypeMatches(t1) && BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t2)) + || (BuiltinTypes::node->xdtTypeMatches(t2) && BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t1))) + { + /* One operand contains nodes and the other atomic values, or vice versa. They can never + * be identical. */ + // TODO warn? + return wrapLiteral(CommonValues::BooleanFalse, context, this); + } + else + { + // TODO Warn? + return me; + } + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qdeepequalfn_p.h b/src/xmlpatterns/functions/qdeepequalfn_p.h new file mode 100644 index 0000000..6272b08 --- /dev/null +++ b/src/xmlpatterns/functions/qdeepequalfn_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DeepEqualFN_H +#define Patternist_DeepEqualFN_H + +#include "qatomiccomparator_p.h" +#include "qcomparisonplatform_p.h" +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function <tt>fn:deep-equal()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class DeepEqualFN : public FunctionCall, + public ComparisonPlatform<DeepEqualFN, false> + { + public: + inline DeepEqualFN() : ComparisonPlatform<DeepEqualFN, false>() + { + } + + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + inline AtomicComparator::Operator operatorID() const + { + return AtomicComparator::OperatorEqual; + } + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qdocumentfn.cpp b/src/xmlpatterns/functions/qdocumentfn.cpp new file mode 100644 index 0000000..02f28d9 --- /dev/null +++ b/src/xmlpatterns/functions/qdocumentfn.cpp @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qforclause_p.h" +#include "qfunctionfactory_p.h" +#include "qrangevariablereference_p.h" + +#include "qdocumentfn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Expression::Ptr DocumentFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + /* See the class documentation for the rewrite that we're doing here. */ + + /* Generate type checking code for our operands such that they match. */ + typeCheckOperands(context); + + const QSourceLocation myLocation(context->locationFor(this)); + const FunctionFactory::Ptr functions(context->functionSignatures()); + + Expression::Ptr uriSource; + + { + Expression::List distinctValuesArgs; + distinctValuesArgs.append(m_operands.first()); + + uriSource = functions->createFunctionCall(QXmlName(StandardNamespaces::fn, StandardLocalNames::distinct_values), + distinctValuesArgs, + context, + this); + context->addLocation(uriSource.data(), myLocation); + } + + const VariableSlotID rangeSlot = context->allocateRangeSlot(); + const Expression::Ptr uriReference(new RangeVariableReference(uriSource, rangeSlot)); + context->addLocation(uriReference.data(), myLocation); + + Expression::List docArgs; + + if(m_operands.count() == 2) + { + Expression::List baseUriArgs; + baseUriArgs.append(uriReference); + baseUriArgs.append(m_operands.at(1)); + + const Expression::Ptr fnBaseUri(functions->createFunctionCall(QXmlName(StandardNamespaces::fn, StandardLocalNames::resolve_uri), + baseUriArgs, + context, + this)); + context->addLocation(fnBaseUri.data(), myLocation); + docArgs.append(fnBaseUri); + } + else + docArgs.append(uriReference); + + const Expression::Ptr fnDoc(functions->createFunctionCall(QXmlName(StandardNamespaces::fn, StandardLocalNames::doc), + docArgs, + context, + this)); + context->addLocation(fnDoc.data(), myLocation); + + + Expression::Ptr newMe(new ForClause(rangeSlot, + uriSource, + fnDoc, + -1 /* We have no position variable. */)); + + Expression::Ptr oldMe(this); + rewrite(oldMe, newMe, context); + return newMe->typeCheck(context, reqType); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qdocumentfn_p.h b/src/xmlpatterns/functions/qdocumentfn_p.h new file mode 100644 index 0000000..74dcd31 --- /dev/null +++ b/src/xmlpatterns/functions/qdocumentfn_p.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DocumentFN_H +#define Patternist_DocumentFN_H + +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements XSL-T's function <tt>fn:document()</tt>. + * + * @c fn:document() has no evaluation functions, because it rewrites + * itself to a set of expressions that is the implementation. + * + * The two-argument version: + * + * <tt>document($uris as item()*, $baseURINode as node()) as node()*</tt> + * + * is rewritten into: + * + * <tt>for $uri in distinct-values($uris) + * return doc(resolve-uri($uri, base-uri($baseURINode)))</tt> + * + * and the single version argument: + * + * <tt>document($uris as item()*) as node()*</tt> + * + * is rewritten into: + * + * <tt>for $uri in distinct-values($uris) + * return doc($uri)</tt> + * + * The distinct-values() call ensures the node deduplication and sorting, + * although it fails in the case that URIs resolve/directs in some way to + * the same document. Some of those cases can be solved by wrapping the + * whole expression with a node deduplication(conceptually the-for-loop/.). + * One advantage with distinct-values() over generating traditional node + * sorting/deduplication code is that the latter contains node sorting + * which is uecessary and can be hard to analyze away. distinct-values() + * doesn't have this problem due to its narrower task.. + * + * This works without problems, assuming XTRE1160 is not raised and that + * the recover action instead is ignore. In the case XTRE1160 is raised, + * one must cater for this. + * + * In addition to this, both signatures has its first argument changed to + * type <tt>xs:string*</tt>, in order to generate atomization code. + * + * One notable thing is that the expression for $baseURINode, is moved + * inside a loop, and will be evaluated repeatedly, unless moved out as + * part of optimization. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + * @since 4.5 + */ + class DocumentFN : public FunctionCall + { + public: + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qelementavailablefn.cpp b/src/xmlpatterns/functions/qelementavailablefn.cpp new file mode 100644 index 0000000..853b2d0 --- /dev/null +++ b/src/xmlpatterns/functions/qelementavailablefn.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnameconstructor_p.h" + +#include "qelementavailablefn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ElementAvailableFN::ElementAvailableFN() : m_xsltInstructions(allXSLTInstructions()) +{ +} + +QSet<QString> ElementAvailableFN::allXSLTInstructions() +{ + enum + { + StringSetSize = 27 + }; + + QSet<QString> retval; + retval.reserve(StringSetSize); + + /* Alphabetically. */ + retval.insert(QLatin1String("analyze-string")); + retval.insert(QLatin1String("apply-imports")); + retval.insert(QLatin1String("apply-templates")); + retval.insert(QLatin1String("attribute")); + retval.insert(QLatin1String("attribute-set")); + retval.insert(QLatin1String("call-template")); + retval.insert(QLatin1String("character-map")); + retval.insert(QLatin1String("choose")); + retval.insert(QLatin1String("comment")); + retval.insert(QLatin1String("copy")); + retval.insert(QLatin1String("copy-of")); + retval.insert(QLatin1String("document")); + retval.insert(QLatin1String("element")); + retval.insert(QLatin1String("fallback")); + retval.insert(QLatin1String("for-each")); + retval.insert(QLatin1String("for-each-group")); + retval.insert(QLatin1String("if")); + retval.insert(QLatin1String("message")); + retval.insert(QLatin1String("namespace")); + retval.insert(QLatin1String("next-match")); + retval.insert(QLatin1String("number")); + retval.insert(QLatin1String("perform-sort")); + retval.insert(QLatin1String("processing-instruction")); + retval.insert(QLatin1String("result-document")); + retval.insert(QLatin1String("sequence")); + retval.insert(QLatin1String("text")); + retval.insert(QLatin1String("variable")); + + Q_ASSERT(retval.count() == StringSetSize); + return retval; +} + +bool ElementAvailableFN::evaluateEBV(const DynamicContext::Ptr &context) const +{ + const Item arg(m_operands.first()->evaluateSingleton(context)); + const QString stringName(arg.stringValue()); + + const QXmlName elementName(QNameConstructor::expandQName<DynamicContext::Ptr, + ReportContext::XTDE1440, + ReportContext::XTDE1440>(stringName, + context, + staticNamespaces(), + this, + false)); + + if(elementName.namespaceURI() != StandardNamespaces::xslt) + return false; + + QString prefix; + QString localName; + XPathHelper::splitQName(stringName, prefix, localName); + + return m_xsltInstructions.contains(localName); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qelementavailablefn_p.h b/src/xmlpatterns/functions/qelementavailablefn_p.h new file mode 100644 index 0000000..3ea1650 --- /dev/null +++ b/src/xmlpatterns/functions/qelementavailablefn_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ElementAvailableFN_H +#define Patternist_ElementAvailableFN_H + +#include "qstaticnamespacescontainer_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function <tt>fn:unparsed-text()</tt>. + * + * @ingroup Patternist_functions + * @see <a href="http://www.w3.org/TR/xslt20/#unparsed-text">XSL + * Transformations (XSLT) Version 2.0, 16.2 unparsed-text</a> + * @author Frans Englich <fenglich@trolltech.com> + * @since 4.5 + */ + class ElementAvailableFN : public StaticNamespacesContainer + { + public: + ElementAvailableFN(); + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + + private: + static QSet<QString> allXSLTInstructions(); + const QSet<QString> m_xsltInstructions; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qerrorfn.cpp b/src/xmlpatterns/functions/qerrorfn.cpp new file mode 100644 index 0000000..5cef1b6 --- /dev/null +++ b/src/xmlpatterns/functions/qerrorfn.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qpatternistlocale_p.h" +#include "qqnamevalue_p.h" +#include "qatomicstring_p.h" + +#include "qerrorfn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +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(); + } + } +} + +FunctionSignature::Ptr ErrorFN::signature() const +{ + const FunctionSignature::Ptr e(FunctionCall::signature()); + + if(m_operands.count() != 1) + return e; + + FunctionSignature::Ptr nev(FunctionSignature::Ptr(new FunctionSignature(e->name(), + e->minimumArguments(), + e->maximumArguments(), + e->returnType(), + e->properties()))); + const FunctionArgument::List args(e->arguments()); + FunctionArgument::List nargs; + const QXmlName argName(StandardNamespaces::empty, StandardLocalNames::error); + nargs.append(FunctionArgument::Ptr(new FunctionArgument(argName, CommonSequenceTypes::ExactlyOneQName))); + nargs.append(args[1]); + nargs.append(args[2]); + nev->setArguments(nargs); + + return nev; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qerrorfn_p.h b/src/xmlpatterns/functions/qerrorfn_p.h new file mode 100644 index 0000000..2598589 --- /dev/null +++ b/src/xmlpatterns/functions/qerrorfn_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ErrorFN_H +#define Patternist_ErrorFN_H + +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements the function <tt>fn:error()</tt>. + * + * <tt>fn:error()</tt> is a bit special in that its first argument varies between + * the different signatures. This is implemented by changing the function + * signature if the amount of arguments is one. + * + * <tt>fn:error()</tt> has as return type the peculiar "none" type, which is handled by NoneType. + * + * @ingroup Patternist_functions + * @see CommonSequenceTypes::none + * @see <a href="http://www.w3.org/TR/xpath-functions/#func-error">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 3 The Error Function</a> + * @author Frans Englich <fenglich@trolltech.com> + */ + class ErrorFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual FunctionSignature::Ptr signature() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qfunctionargument.cpp b/src/xmlpatterns/functions/qfunctionargument.cpp new file mode 100644 index 0000000..63cf00f --- /dev/null +++ b/src/xmlpatterns/functions/qfunctionargument.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfunctionargument_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +FunctionArgument::FunctionArgument(const QXmlName nameP, + const SequenceType::Ptr &typeP) : m_name(nameP), + m_type(typeP) +{ + Q_ASSERT(!nameP.isNull()); + Q_ASSERT(typeP); +} + +QXmlName FunctionArgument::name() const +{ + return m_name; +} + +SequenceType::Ptr FunctionArgument::type() const +{ + return m_type; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qfunctionargument_p.h b/src/xmlpatterns/functions/qfunctionargument_p.h new file mode 100644 index 0000000..2703e56 --- /dev/null +++ b/src/xmlpatterns/functions/qfunctionargument_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_FunctionArgument_H +#define Patternist_FunctionArgument_H + +#include <QList> +#include <QSharedData> + +#include "qxmlname.h" +#include "qsequencetype_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Carries meta data for a function argument as found in XPath's + * builtin functions and user declared functions in XQuery and XSL-T. + * + * @ingroup Patternist_functions + * @see VariableDeclaration + * @author Frans Englich <fenglich@trolltech.com> + */ + class FunctionArgument : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer<FunctionArgument> Ptr; + typedef QList<FunctionArgument::Ptr> List; + + FunctionArgument(const QXmlName name, + const SequenceType::Ptr &type); + + QXmlName name() const; + SequenceType::Ptr type() const; + + private: + Q_DISABLE_COPY(FunctionArgument) + const QXmlName m_name; + const SequenceType::Ptr m_type; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qfunctionavailablefn.cpp b/src/xmlpatterns/functions/qfunctionavailablefn.cpp new file mode 100644 index 0000000..20c08fa --- /dev/null +++ b/src/xmlpatterns/functions/qfunctionavailablefn.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qboolean_p.h" +#include "qdelegatingnamespaceresolver_p.h" +#include "qinteger_p.h" +#include "qqnameconstructor_p.h" + +#include "qfunctionavailablefn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item FunctionAvailableFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const QString lexQName(m_operands.first()->evaluateSingleton(context).stringValue()); + + NamespaceResolver::Bindings override; + override.insert(StandardPrefixes::empty, m_defFuncNS); + + const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(staticNamespaces(), override)); + + const QXmlName name + (QNameConstructor::expandQName<DynamicContext::Ptr, + ReportContext::XTDE1400, + ReportContext::XTDE1400>(lexQName, + context, + resolver, + this)); + + xsInteger arity; + + if(m_operands.count() == 2) + arity = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()->toInteger(); + else + arity = FunctionSignature::UnlimitedArity; + + return Boolean::fromValue(m_functionFactory->isAvailable(context->namePool(), name, arity)); +} + +Expression::Ptr FunctionAvailableFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + m_functionFactory = context->functionSignatures(); + Q_ASSERT(m_functionFactory); + m_defFuncNS = context->namePool()->allocateNamespace(context->defaultFunctionNamespace()); + /* m_defFuncNS can be empty/null or an actual value. */ + + return StaticNamespacesContainer::typeCheck(context, reqType); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qfunctionavailablefn_p.h b/src/xmlpatterns/functions/qfunctionavailablefn_p.h new file mode 100644 index 0000000..b8ed8d2 --- /dev/null +++ b/src/xmlpatterns/functions/qfunctionavailablefn_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_FunctionAvailableFN_H +#define Patternist_FunctionAvailableFN_H + +#include "qstaticnamespacescontainer_p.h" +#include "qfunctionfactory_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements XSL-T 2.0's XPath function <tt>fn:function-available()</tt>. + * + * @see <a href="http://www.w3.org/TR/xslt20/#function-function-available">XSL Transformations + * (XSLT) Version 2.0, 18.1.1 Testing Availability of Functions</a> + * @author Frans Englich <fenglich@trolltech.com> + * @ingroup Patternist_functions + */ + class FunctionAvailableFN : public StaticNamespacesContainer + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + /** + * Reimplemented to store data from the @p context which is needed at runtime. + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + private: + FunctionFactory::Ptr m_functionFactory; + QXmlName::NamespaceCode m_defFuncNS; + }; + +QT_END_NAMESPACE +} +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qfunctioncall.cpp b/src/xmlpatterns/functions/qfunctioncall.cpp new file mode 100644 index 0000000..edea72f --- /dev/null +++ b/src/xmlpatterns/functions/qfunctioncall.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qcontextitem_p.h" +#include "qcommonsequencetypes_p.h" +#include "qemptysequence_p.h" +#include "qfunctionsignature_p.h" +#include "qgenericsequencetype_p.h" +#include "qcollationchecker_p.h" +#include "qcommonnamespaces_p.h" + +#include "qfunctioncall_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +SequenceType::List FunctionCall::expectedOperandTypes() const +{ + const FunctionArgument::List args(signature()->arguments()); + FunctionArgument::List::const_iterator it(args.constBegin()); + const FunctionArgument::List::const_iterator end(args.constEnd()); + // TODO reserve/resize() + SequenceType::List result; + + for(; it != end; ++it) + result.append((*it)->type()); + + return result; +} + +Expression::Ptr FunctionCall::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + /* We don't cache properties() at some stages because it can be invalidated + * by the typeCheck(). */ + + const FunctionSignature::Arity maxArgs = signature()->maximumArguments(); + /* We do this before the typeCheck() such that the appropriate conversions + * are applied to the ContextItem. */ + if(m_operands.count() < maxArgs && + has(UseContextItem)) + { + m_operands.append(Expression::Ptr(new ContextItem())); + context->wrapExpressionWith(this, m_operands.last()); + } + + const Expression::Ptr me(UnlimitedContainer::typeCheck(context, reqType)); + if(me != this) + return me; + + const Properties props(properties()); + + if(props.testFlag(RewriteToEmptyOnEmpty) && + *CommonSequenceTypes::Empty == *m_operands.first()->staticType()->itemType()) + { + return EmptySequence::create(this, context); + } + + if(props.testFlag(LastOperandIsCollation) && + m_operands.count() == maxArgs) + { + m_operands.last() = Expression::Ptr(new CollationChecker(m_operands.last())); + context->wrapExpressionWith(this, m_operands.last()); + } + + return me; +} + +void FunctionCall::setSignature(const FunctionSignature::Ptr &sign) +{ + m_signature = sign; +} + +FunctionSignature::Ptr FunctionCall::signature() const +{ + Q_ASSERT(m_signature); /* It really should be set. */ + return m_signature; +} + +SequenceType::Ptr FunctionCall::staticType() const +{ + Q_ASSERT(m_signature); + if(has(EmptynessFollowsChild)) + { + if(m_operands.isEmpty()) + { + /* This is a function which uses the context item when having no arguments. */ + return signature()->returnType(); + } + const Cardinality card(m_operands.first()->staticType()->cardinality()); + if(card.allowsEmpty()) + return signature()->returnType(); + else + { + /* Remove empty. */ + return makeGenericSequenceType(signature()->returnType()->itemType(), + card & Cardinality::oneOrMore()); + } + } + return signature()->returnType(); +} + +Expression::Properties FunctionCall::properties() const +{ + Q_ASSERT(m_signature); + return signature()->properties(); +} + +ExpressionVisitorResult::Ptr FunctionCall::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID FunctionCall::id() const +{ + Q_ASSERT(m_signature); + return m_signature->id(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qfunctioncall_p.h b/src/xmlpatterns/functions/qfunctioncall_p.h new file mode 100644 index 0000000..4d1123a --- /dev/null +++ b/src/xmlpatterns/functions/qfunctioncall_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_FunctionCall_H +#define Patternist_FunctionCall_H + +#include "qunlimitedcontainer_p.h" +#include "qfunctionsignature_p.h" +#include "qxpathhelper_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for implementations of builtin functions. + * + * However, it doesn't handle user declared functions. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class FunctionCall : public UnlimitedContainer + { + public: + typedef QExplicitlySharedDataPointer<FunctionCall> Ptr; + + virtual SequenceType::List expectedOperandTypes() const; + virtual SequenceType::Ptr staticType() const; + + virtual void setSignature(const FunctionSignature::Ptr &sign); + virtual FunctionSignature::Ptr signature() const; + + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + virtual Expression::Properties properties() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + virtual ID id() const; + + private: + FunctionSignature::Ptr m_signature; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qfunctionfactory.cpp b/src/xmlpatterns/functions/qfunctionfactory.cpp new file mode 100644 index 0000000..6809bb2 --- /dev/null +++ b/src/xmlpatterns/functions/qfunctionfactory.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfunctionsignature_p.h" + +#include "qfunctionfactory_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +FunctionFactory::~FunctionFactory() +{ +} + +bool FunctionFactory::isAvailable(const NamePool::Ptr &np, + const QXmlName name, const xsInteger arity) +{ + const FunctionSignature::Ptr sign(retrieveFunctionSignature(np, name)); + + if(sign) + return arity == FunctionSignature::UnlimitedArity || sign->isArityValid(arity); + else + return false; +} + +bool FunctionFactory::hasSignature(const FunctionSignature::Ptr &signature) const +{ + const FunctionSignature::Hash signs(functionSignatures()); + const FunctionSignature::Hash::const_iterator end(signs.constEnd()); + FunctionSignature::Hash::const_iterator it(signs.constBegin()); + + for(; it != end; ++it) + { + if(*(*it) == *signature) + return true; + } + + return false; +} +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qfunctionfactory_p.h b/src/xmlpatterns/functions/qfunctionfactory_p.h new file mode 100644 index 0000000..e0a7d4a --- /dev/null +++ b/src/xmlpatterns/functions/qfunctionfactory_p.h @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + + +#ifndef Patternist_FunctionFactory_H +#define Patternist_FunctionFactory_H + +#include <QHash> +#include <QSharedData> + +#include "qexpression_p.h" +#include "qfunctionsignature_p.h" +#include "qprimitives_p.h" +#include "qxmlname.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short An entry point for looking up and creating FunctionCall instances. + * + * @ingroup Patternist_functions + * @see <a href ="http://www.w3.org/TR/xpath-functions/">XQuery 1.0 + * and XPath 2.0 Functions and Operators</a> + * @see <a href="http://www.w3.org/TR/xpath20/#dt-function-signature">XML Path + * Language (XPath) 2.0, Definition: Function signatures</a> + * @author Frans Englich <fenglich@trolltech.com> + */ + class FunctionFactory : public QSharedData + { + public: + + typedef QExplicitlySharedDataPointer<FunctionFactory> Ptr; + typedef QList<FunctionFactory::Ptr> List; + + virtual ~FunctionFactory(); + + /** + * Creates a function call implementation. + * + * A FunctionFactory represents a set of functions, which it + * is able to instantiate and to serve FunctionSignatures for. Conventionally, + * a FunctionFactory per namespace exists. + * + * @note This function should not issue any error unless it is absolutely + * confident that the error cannot be fixed in another way. For example, in + * some cases it might be that a function is available in another FunctionFactory + * and it would therefore be wrong to issue an error signalling that no function + * by that @p name exists, but leave that to the callee. + * @param name the name of the function to create. In Clark syntax, this could + * for example be {http://www.w3.org/2005/04/xpath-functions}lower-case + * @param arguments the function's operands + * @param context the usual StaticContext which supplies compile time data + * and reporting functionality. + * @param r the SourceLocationReflection that identifies the callsite. + * @returns an instance of Expression which is the function implementation + * for @p name. Or, a static error was raised. + */ + virtual Expression::Ptr createFunctionCall(const QXmlName name, + const Expression::List &arguments, + const StaticContext::Ptr &context, + const SourceLocationReflection *const r) = 0; + + /** + * Determines whether a function with the name @p name and arity @p arity + * is available. The implementation operates on the result of + * retrieveFunctionSignature() to determine the result. + * + * @param np the NamePool. + * @param name the name of the function. For example fn:string-join. + * @param arity the number of arguments the function must have. + */ + virtual bool isAvailable(const NamePool::Ptr &np, + const QXmlName name, + const xsInteger arity); + + virtual FunctionSignature::Hash functionSignatures() const = 0; + + /** + * Determines whether this FunctionFactory contains the function signature + * @p signature. + * + * The implementation uses functionSignatures(). + */ + bool hasSignature(const FunctionSignature::Ptr &signature) const; + + protected: + /** + * @short This constructor cannot be removed, because it can't be synthesized, for + * some reason. + */ + inline FunctionFactory() + { + } + + /** + * This is a convenience function for sub-classes. It retrieves the + * function signature for function with name @p name. + * + * According to the specifications are function signatures identified by their + * name and arity, but currently is the arity not part of the signature. + * + * If no function could be found for the given name, @c null is returned. + */ + virtual FunctionSignature::Ptr retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name) = 0; + + private: + Q_DISABLE_COPY(FunctionFactory) + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qfunctionfactorycollection.cpp b/src/xmlpatterns/functions/qfunctionfactorycollection.cpp new file mode 100644 index 0000000..00856f4 --- /dev/null +++ b/src/xmlpatterns/functions/qfunctionfactorycollection.cpp @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbasictypesfactory_p.h" +#include "qconstructorfunctionsfactory_p.h" +#include "qfunctioncall_p.h" +#include "qxpath10corefunctions_p.h" +#include "qxpath20corefunctions_p.h" +#include "qxslt20corefunctions_p.h" + +#include "qfunctionfactorycollection_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Expression::Ptr FunctionFactoryCollection::createFunctionCall(const QXmlName name, + const Expression::List &arguments, + const StaticContext::Ptr &context, + const SourceLocationReflection *const r) +{ + const_iterator it; + const_iterator e(constEnd()); + Expression::Ptr function; + + for(it = constBegin(); it != e; ++it) + { + function = (*it)->createFunctionCall(name, arguments, context, r); + + if(function) + break; + } + + return function; +} + +bool FunctionFactoryCollection::isAvailable(const NamePool::Ptr &np, const QXmlName name, const xsInteger arity) +{ + const_iterator it; + const_iterator e(constEnd()); + + for(it = constBegin(); it != e; ++it) + if((*it)->isAvailable(np, name, arity)) + return true; + + return false; +} + +FunctionSignature::Hash FunctionFactoryCollection::functionSignatures() const +{ + /* We simply grab the function signatures for each library, and + * put them all in one list. */ + + const const_iterator e(constEnd()); + FunctionSignature::Hash result; + + for(const_iterator it(constBegin()); it != e; ++it) + { + const FunctionSignature::Hash::const_iterator e2((*it)->functionSignatures().constEnd()); + FunctionSignature::Hash::const_iterator sit((*it)->functionSignatures().constBegin()); + + for(; sit != e2; ++sit) + result.insert(sit.key(), sit.value()); + } + + return result; +} + +FunctionSignature::Ptr FunctionFactoryCollection::retrieveFunctionSignature(const NamePool::Ptr &, const QXmlName name) +{ + return functionSignatures().value(name); +} + +FunctionFactory::Ptr FunctionFactoryCollection::xpath10Factory() +{ + /* We don't use a global static for caching this, because AbstractFunctionFactory + * stores state specific to the NamePool, when being used. */ + return FunctionFactory::Ptr(new XPath10CoreFunctions()); +} + +FunctionFactory::Ptr FunctionFactoryCollection::xpath20Factory(const NamePool::Ptr &np) +{ + /* We don't use a global static for caching this, because AbstractFunctionFactory + * stores state specific to the NamePool, when being used. */ + const FunctionFactoryCollection::Ptr fact(new FunctionFactoryCollection()); + fact->append(xpath10Factory()); + fact->append(FunctionFactory::Ptr(new XPath20CoreFunctions())); + fact->append(FunctionFactory::Ptr( + new ConstructorFunctionsFactory(np, BasicTypesFactory::self(np)))); + return fact; +} + +FunctionFactory::Ptr FunctionFactoryCollection::xslt20Factory(const NamePool::Ptr &np) +{ + const FunctionFactory::Ptr retval(xpath20Factory(np)); + static_cast<FunctionFactoryCollection *>(retval.data())->append(FunctionFactory::Ptr(new XSLT20CoreFunctions())); + return retval; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qfunctionfactorycollection_p.h b/src/xmlpatterns/functions/qfunctionfactorycollection_p.h new file mode 100644 index 0000000..f83aaac --- /dev/null +++ b/src/xmlpatterns/functions/qfunctionfactorycollection_p.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + + +#ifndef Patternist_FunctionFactoryCollection_H +#define Patternist_FunctionFactoryCollection_H + +#include "qfunctionfactory_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A FunctionFactoryCollection instance is a FunctionFactory in its own right, + * but looks in its contained collection of factories for requested functions. + * + * @note the order of adding function libraries is significant. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class Q_AUTOTEST_EXPORT FunctionFactoryCollection: public FunctionFactory + , public FunctionFactory::List + { + public: + + typedef QExplicitlySharedDataPointer<FunctionFactoryCollection> Ptr; + + /** + * Creates a function call node. + */ + virtual Expression::Ptr createFunctionCall(const QXmlName, + const Expression::List &arguments, + const StaticContext::Ptr &context, + const SourceLocationReflection *const r); + virtual bool isAvailable(const NamePool::Ptr &np, const QXmlName name, const xsInteger arity); + + virtual FunctionSignature::Hash functionSignatures() const; + + virtual FunctionSignature::Ptr retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name); + + /** + * @return a FunctionFactory containing all core functions and constructor + * functions required for XPath 2.. The functions specified for XQuery 1.0 + * are the same as for XPath 2.0 so this FunctionFactory work for XQuery + * as well. + */ + static FunctionFactory::Ptr xpath20Factory(const NamePool::Ptr &np); + + /** + * @return a FunctionFactory containing all core functions required for XPath 1.0. + */ + static FunctionFactory::Ptr xpath10Factory(); + + /** + * @return a FunctionFactory containing all core functions required for XSL-T 2.0 + * functions. + */ + static FunctionFactory::Ptr xslt20Factory(const NamePool::Ptr &np); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qfunctionsignature.cpp b/src/xmlpatterns/functions/qfunctionsignature.cpp new file mode 100644 index 0000000..15f9cff --- /dev/null +++ b/src/xmlpatterns/functions/qfunctionsignature.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qxmlname.h" + +#include "qfunctionsignature_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +FunctionSignature::FunctionSignature(const QXmlName nameP, + const Arity minArgs, + const Arity maxArgs, + const SequenceType::Ptr &returnTypeP, + const Expression::Properties props, + const Expression::ID idP) : CallTargetDescription(nameP) + , m_minArgs(minArgs) + , m_maxArgs(maxArgs) + , m_returnType(returnTypeP) + , m_arguments() + , m_props(props) + , m_id(idP) +{ + Q_ASSERT(minArgs <= maxArgs || maxArgs == FunctionSignature::UnlimitedArity); + Q_ASSERT(m_maxArgs >= -1); + Q_ASSERT(returnTypeP); +} + +void FunctionSignature::appendArgument(const QXmlName::LocalNameCode nameP, + const SequenceType::Ptr &type) +{ + Q_ASSERT(type); + + m_arguments.append(FunctionArgument::Ptr(new FunctionArgument(QXmlName(StandardNamespaces::empty, nameP), type))); +} + +QString FunctionSignature::displayName(const NamePool::Ptr &np) const +{ + QString result; + result += np->displayName(name()); + result += QLatin1Char('('); + + FunctionArgument::List::const_iterator it(m_arguments.constBegin()); + const FunctionArgument::List::const_iterator end(m_arguments.constEnd()); + + if(it != end) + { + while(true) + { + result += QLatin1Char('$'); + result += np->displayName((*it)->name()); + result += QLatin1String(" as "); + result += (*it)->type()->displayName(np); + + ++it; + if(it == end) + break; + + result += QLatin1String(", "); + } + } + + if(m_maxArgs == FunctionSignature::UnlimitedArity) + result += QLatin1String(", ..."); + + result += QLatin1String(") as "); + result += m_returnType->displayName(np); + + return result; +} + +bool FunctionSignature::operator==(const FunctionSignature &other) const +{ + return name() == other.name() && + isArityValid(other.maximumArguments()) && + isArityValid(other.minimumArguments()); +} + +void FunctionSignature::setArguments(const FunctionArgument::List &args) +{ + m_arguments = args; +} + +FunctionArgument::List FunctionSignature::arguments() const +{ + return m_arguments; +} + +bool FunctionSignature::isArityValid(const xsInteger arity) const +{ + return arity >= m_minArgs && arity <= m_maxArgs; +} + +FunctionSignature::Arity FunctionSignature::minimumArguments() const +{ + return m_minArgs; +} + +FunctionSignature::Arity FunctionSignature::maximumArguments() const +{ + return m_maxArgs; +} + +SequenceType::Ptr FunctionSignature::returnType() const +{ + return m_returnType; +} + +Expression::Properties FunctionSignature::properties() const +{ + return m_props; +} + +Expression::ID FunctionSignature::id() const +{ + return m_id; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qfunctionsignature_p.h b/src/xmlpatterns/functions/qfunctionsignature_p.h new file mode 100644 index 0000000..4dcd4cc --- /dev/null +++ b/src/xmlpatterns/functions/qfunctionsignature_p.h @@ -0,0 +1,213 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_FunctionSignature_H +#define Patternist_FunctionSignature_H + +template<typename Key, typename Value> class QHash; +template<typename T> class QList; + +#include <QSharedData> + +#include "qcalltargetdescription_p.h" +#include "qexpression_p.h" +#include "qfunctionargument_p.h" +#include "qpatternistlocale_p.h" +#include "qprimitives_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Represents the signature of an XPath function. + * + * FunctionSignature represents and allows inspection of a function signature, + * such as <tt>fn:string-join($arg1 as xs:string*, $arg2 as xs:string) as xs:string</tt>. + * No XPath related languages allows polymorphism on the type of the arguments, only the + * amount(arity) of the arguments. For example, <tt>fn:string() as xs:string</tt> and + * <tt>fn:string($arg as item()?) as xs:string</tt> can happily co-exist, but + * <tt>fn:string($arg as item()?) as xs:string</tt> and + * <tt>fn:string($arg as xs:anyAtomicType?) as xs:string</tt> would be an error. This + * fact is reflected by FunctionSignature that if minimumArguments() and maximumArguments() + * are not equal, it means that this FunctionSignature represents several + * function signatures. + * + * @ingroup Patternist_functions + * @see <a href="http://www.w3.org/TR/xpath-functions/#func-signatures">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 1.4 Function Signatures and Descriptions</a> + * @see <a href="http://en.wikipedia.org/wiki/Arity">Wikipedia, the free encyclopedia, Arity</a> + * @author Frans Englich <fenglich@trolltech.com> + */ + class Q_AUTOTEST_EXPORT FunctionSignature : public CallTargetDescription + { + public: + enum + { + /** + * Flags the function as allowing an unlimited amount of arguments. + */ + UnlimitedArity = -1 + }; + + typedef QExplicitlySharedDataPointer<FunctionSignature> Ptr; + typedef QHash<QXmlName, FunctionSignature::Ptr> Hash; + typedef QList<FunctionSignature::Ptr> List; + + /** + * A number which tells the amount of arguments a function has. + */ + typedef qint16 Arity; + + FunctionSignature(const QXmlName name, + const Arity minArgs, + const Arity maxArgs, + const SequenceType::Ptr &returnType, + const Expression::Properties chars = Expression::Properties(), + const Expression::ID id = Expression::IDIgnorableExpression); + + void setArguments(const FunctionArgument::List &args); + FunctionArgument::List arguments() const; + + /** + * This is a convenience function. Calling this once, is equal to + * calling setArguments() with a list containing a FunctionsArgument with name @p name + * and type @p type. + */ + void appendArgument(const QXmlName::LocalNameCode name, + const SequenceType::Ptr &type); + + /** + * Checks whether @p arity is within the range of allowed count of arguments. For example, + * when the minimum arguments is 1 and maximum arguments 2, @c false will be returned for + * passing 0 while @c true will be returned when 2 is passed. + */ + bool isArityValid(const xsInteger arity) const; + + Arity minimumArguments() const; + Arity maximumArguments() const; + + /** + * The return type of this function signature. For example, if the represented function + * signature is <tt>fn:string() as xs:string</tt>, the return type is <tt>xs:string</tt>. + */ + SequenceType::Ptr returnType() const; + + /** + * The properties that the corresponding FunctionCall instance should return in + * Expression::properties(). + */ + Expression::Properties properties() const; + + /** + * Determines whether this FunctionSignature is equal to @p other, taking + * into account XPath's function polymorphism. @p other is equal to this + * FunctionSignature if their name() instances are equal, and that the maximumArguments() + * and minimumArguments() arguments of @p other are allowed, as per isArityValid(). + * + * In other words, this equalness operator can return @c true for different + * signatures, but it do make sense since a FunctionSignature can represent + * multiple signatures. + * + * @returns @c true if this FunctionSignature is equal to @p other, otherwise @c false + */ + bool operator==(const FunctionSignature &other) const; + + /** + * Builds a string representation for this function signature. The syntax + * used is the one used in the XQuery. It looks like this: + * + * <tt>prefix:function-name($parameter-name as parameter-type, ...) as return-type</tt> + * + * The prefix used for the name is conventional. For example, for constructor functions + * is @c xs used. + * + * @see <a href="http://www.w3.org/TR/xpath-functions/#func-signatures">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 1.4 Function Signatures and Descriptions</a> + */ + QString displayName(const NamePool::Ptr &np) const; + + /** + * The ID that the corresponding FunctionCall instance should return in + * Expression::id(). + */ + Expression::ID id() const; + + private: + Q_DISABLE_COPY(FunctionSignature) + + const Arity m_minArgs; + const Arity m_maxArgs; + const SequenceType::Ptr m_returnType; + FunctionArgument::List m_arguments; + const Expression::Properties m_props; + const Expression::ID m_id; + }; + + /** + * @short Formats FunctionSignature. + */ + static inline QString formatFunction(const NamePool::Ptr &np, const FunctionSignature::Ptr &func) + { + return QLatin1String("<span class='XQuery-function'>") + + escape(func->displayName(np)) + + QLatin1String("</span>"); + } +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qgenerateidfn.cpp b/src/xmlpatterns/functions/qgenerateidfn.cpp new file mode 100644 index 0000000..c1913da --- /dev/null +++ b/src/xmlpatterns/functions/qgenerateidfn.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qatomicstring_p.h" + +#include "qgenerateidfn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item GenerateIDFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const QXmlNodeModelIndex &node = m_operands.first()->evaluateSingleton(context).asNode(); + + if(node.isNull()) + return AtomicString::fromValue(QString()); + + return AtomicString::fromValue(QLatin1Char('T') + + QString::number(qptrdiff(node.model())) + + QString::number(qptrdiff(node.internalPointer())) + + QString::number(node.additionalData())); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qgenerateidfn_p.h b/src/xmlpatterns/functions/qgenerateidfn_p.h new file mode 100644 index 0000000..54b94cd --- /dev/null +++ b/src/xmlpatterns/functions/qgenerateidfn_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_GenerateIDFN_H +#define Patternist_GenerateIDFN_H + +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE +namespace QPatternist +{ + + /** + * @short Implements the function <tt>fn:generate-id()</tt>. + * + * @ingroup Patternist_functions + * @see <a href="http://www.w3.org/TR/xslt20/#generate-id">XSL + * Transformations (XSLT) Version 2.0, 16.6.4 generate-id</a> + * @author Frans Englich <fenglich@trolltech.com> + * @since 4.5 + */ + class GenerateIDFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qnodefns.cpp b/src/xmlpatterns/functions/qnodefns.cpp new file mode 100644 index 0000000..5230a6c --- /dev/null +++ b/src/xmlpatterns/functions/qnodefns.cpp @@ -0,0 +1,209 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstractfloat_p.h" +#include "qanyuri_p.h" +#include "qboolean_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonnamespaces_p.h" +#include "qcommonvalues_p.h" +#include "qliteral_p.h" +#include "qatomicstring_p.h" + +#include "qnodefns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item NameFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item node(m_operands.first()->evaluateSingleton(context)); + + if(node) + { + const QXmlName name(node.asNode().name()); + + if(name.isNull()) + return CommonValues::EmptyString; + else + return AtomicString::fromValue(context->namePool()->toLexical(name)); + } + else + return CommonValues::EmptyString; +} + +Item LocalNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item node(m_operands.first()->evaluateSingleton(context)); + + if(node) + { + const QXmlName name(node.asNode().name()); + + if(name.isNull()) + return CommonValues::EmptyString; + else + return AtomicString::fromValue(context->namePool()->stringForLocalName(name.localName())); + } + else + return CommonValues::EmptyString; +} + +Item NamespaceURIFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item node(m_operands.first()->evaluateSingleton(context)); + + if(node) + { + const QXmlName name(node.asNode().name()); + + if(name.isNull()) + return CommonValues::EmptyAnyURI; + else + return toItem(AnyURI::fromValue(context->namePool()->stringForNamespace(name.namespaceURI()))); + } + else + return CommonValues::EmptyAnyURI; +} + +Item NumberFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item item(m_operands.first()->evaluateSingleton(context)); + + if(!item) + return CommonValues::DoubleNaN; + + const Item val(cast(item, context)); + Q_ASSERT(val); + + if(val.as<AtomicValue>()->hasError()) + return CommonValues::DoubleNaN; + else + return val; +} + +Expression::Ptr NumberFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + const Expression::Ptr me(FunctionCall::typeCheck(context, reqType)); + const ItemType::Ptr sourceType(m_operands.first()->staticType()->itemType()); + + if(BuiltinTypes::xsDouble->xdtTypeMatches(sourceType)) + { + /* The operand is already xs:double, no need for fn:number(). */ + return m_operands.first()->typeCheck(context, reqType); + } + else if(prepareCasting(context, sourceType)) + return me; + else + { + /* Casting to xs:double will never succeed and we would always return NaN.*/ + return wrapLiteral(CommonValues::DoubleNaN, context, this)->typeCheck(context, reqType); + } +} + +bool LangFN::isLangMatch(const QString &candidate, const QString &toMatch) +{ + if(QString::compare(candidate, toMatch, Qt::CaseInsensitive) == 0) + return true; + + return candidate.startsWith(toMatch, Qt::CaseInsensitive) + && candidate.length() > toMatch.length() + && candidate.at(toMatch.length()) == QLatin1Char('-'); +} + +Item LangFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item langArg(m_operands.first()->evaluateSingleton(context)); + const QString lang(langArg ? langArg.stringValue() : QString()); + + const QXmlName xmlLang(StandardNamespaces::xml, StandardLocalNames::lang, StandardPrefixes::xml); + const QXmlNodeModelIndex langNode(m_operands.at(1)->evaluateSingleton(context).asNode()); + + const QXmlNodeModelIndex::Iterator::Ptr ancestors(langNode.iterate(QXmlNodeModelIndex::AxisAncestorOrSelf)); + QXmlNodeModelIndex ancestor(ancestors->next()); + + while(!ancestor.isNull()) + { + const QXmlNodeModelIndex::Iterator::Ptr attributes(ancestor.iterate(QXmlNodeModelIndex::AxisAttribute)); + QXmlNodeModelIndex attribute(attributes->next()); + + while(!attribute.isNull()) + { + Q_ASSERT(attribute.kind() == QXmlNodeModelIndex::Attribute); + + if(attribute.name() == xmlLang) + { + if(isLangMatch(attribute.stringValue(), lang)) + return CommonValues::BooleanTrue; + else + return CommonValues::BooleanFalse; + } + + attribute = attributes->next(); + } + + ancestor = ancestors->next(); + } + + return CommonValues::BooleanFalse; +} + +Item RootFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item arg(m_operands.first()->evaluateSingleton(context)); + + if(arg) + return arg.asNode().root(); + else + return Item(); +} + +SequenceType::Ptr RootFN::staticType() const +{ + if(m_operands.isEmpty()) + return makeGenericSequenceType(BuiltinTypes::node, Cardinality::exactlyOne()); + else + return makeGenericSequenceType(BuiltinTypes::node, m_operands.first()->staticType()->cardinality().toWithoutMany()); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qnodefns_p.h b/src/xmlpatterns/functions/qnodefns_p.h new file mode 100644 index 0000000..e762fe8 --- /dev/null +++ b/src/xmlpatterns/functions/qnodefns_p.h @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_NodeFNs_H +#define Patternist_NodeFNs_H + +#include "qfunctioncall_p.h" +#include "qcastingplatform_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#node-functions">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 14 Functions and Operators on Nodes</a>. + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function <tt>fn:name()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class NameFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:local-name()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class LocalNameFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:namespace-uri()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class NamespaceURIFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:number()</tt>. + * + * NumberFN uses CastingPlatform for performing the actual casting. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class NumberFN : public FunctionCall, + public CastingPlatform<NumberFN, false> + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + /** + * Overridden in order to call CastingPlatform::prepareCasting(). It also + * implements the optimization of rewriting to its operand if its + * type is xs:double(since the <tt>fn:number()</tt> call is in that case superflorous). + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + /** + * @returns always BuiltinTypes::xsDouble. + */ + inline ItemType::Ptr targetType() const + { + return BuiltinTypes::xsDouble; + } + }; + + /** + * @short Implements the function <tt>fn:lang()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class LangFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + private: + static inline bool isLangMatch(const QString &candidate, const QString &toMatch); + }; + + /** + * @short Implements the function <tt>fn:root()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class RootFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + /** + * Infers its cardinality from the argument. + */ + virtual SequenceType::Ptr staticType() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qnumericfns.cpp b/src/xmlpatterns/functions/qnumericfns.cpp new file mode 100644 index 0000000..73e7eda --- /dev/null +++ b/src/xmlpatterns/functions/qnumericfns.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonvalues_p.h" +#include "qgenericsequencetype_p.h" +#include "qschemanumeric_p.h" + +#include "qnumericfns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item FloorFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item num(m_operands.first()->evaluateSingleton(context)); + + if(!num) + return Item(); + + return toItem(num.as<Numeric>()->floor()); +} + +Item AbsFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item num(m_operands.first()->evaluateSingleton(context)); + + if(!num) + return Item(); + + return toItem(num.as<Numeric>()->abs()); +} + +Item RoundFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item num(m_operands.first()->evaluateSingleton(context)); + + if(!num) + return Item(); + + return toItem(num.as<Numeric>()->round()); +} + +Item CeilingFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item num(m_operands.first()->evaluateSingleton(context)); + + if(!num) + return Item(); + + return toItem(num.as<Numeric>()->ceiling()); +} + +Item RoundHalfToEvenFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item num(m_operands.first()->evaluateSingleton(context)); + + if(!num) + return Item(); + + xsInteger scale = 0; + + if(m_operands.count() == 2) + scale = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()->toInteger(); + + return toItem(num.as<Numeric>()->roundHalfToEven(scale)); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qnumericfns_p.h b/src/xmlpatterns/functions/qnumericfns_p.h new file mode 100644 index 0000000..51c9b71 --- /dev/null +++ b/src/xmlpatterns/functions/qnumericfns_p.h @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_NumericFNs_H +#define Patternist_NumericFNs_H + +#include "qaggregator_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#numeric-value-functions">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 6.4 Functions on Numeric Values</a>. + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements the function <tt>fn:floor()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class FloorFN : public Aggregator + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:abs()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class AbsFN : public Aggregator + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:round()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class RoundFN : public Aggregator + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:ceiling()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class CeilingFN : public Aggregator + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:round-half-to-even()</tt>. + * + * @see <a href="http://www.w3.org/TR/xpath-functions/#func-round-half-to-even">XQuery 1.0 + * and XPath 2.0 Functions and Operators, 6.4.5 fn:round-half-to-even</a> + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class RoundHalfToEvenFN : public Aggregator + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qpatternmatchingfns.cpp b/src/xmlpatterns/functions/qpatternmatchingfns.cpp new file mode 100644 index 0000000..f930955 --- /dev/null +++ b/src/xmlpatterns/functions/qpatternmatchingfns.cpp @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QStringList> + +#include "qboolean_p.h" +#include "qcommonvalues_p.h" +#include "qitemmappingiterator_p.h" +#include "qpatternistlocale_p.h" +#include "qatomicstring_p.h" + +#include "qpatternmatchingfns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +MatchesFN::MatchesFN() : PatternPlatform(2) +{ +} + +Item MatchesFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const QRegExp regexp(pattern(context)); + QString input; + + const Item arg(m_operands.first()->evaluateSingleton(context)); + if(arg) + input = arg.stringValue(); + + return Boolean::fromValue(input.contains(regexp)); +} + +ReplaceFN::ReplaceFN() : PatternPlatform(3) +{ +} + +Item ReplaceFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const QRegExp regexp(pattern(context)); + QString input; + + const Item arg(m_operands.first()->evaluateSingleton(context)); + if(arg) + input = arg.stringValue(); + + const QString replacement(m_replacementString.isNull() ? parseReplacement(regexp.numCaptures(), context) + : m_replacementString); + + + return AtomicString::fromValue(input.replace(regexp, replacement)); +} + +QString ReplaceFN::errorAtEnd(const char ch) +{ + return QtXmlPatterns::tr("%1 must be followed by %2 or %3, not at " + "the end of the replacement string.") + .arg(formatKeyword(QLatin1Char(ch))) + .arg(formatKeyword(QLatin1Char('\\'))) + .arg(formatKeyword(QLatin1Char('$'))); +} + +QString ReplaceFN::parseReplacement(const int, + const DynamicContext::Ptr &context) const +{ + // TODO what if there is no groups, can one rewrite to the replacement then? + const QString input(m_operands.at(2)->evaluateSingleton(context).stringValue()); + + QString retval; + retval.reserve(input.size()); + const int len = input.length(); + + for(int i = 0; i < len; ++i) + { + const QChar ch(input.at(i)); + switch(ch.toAscii()) + { + case '$': + { + /* QRegExp uses '\' as opposed to '$' for marking sub groups. */ + retval.append(QLatin1Char('\\')); + + ++i; + if(i == len) + { + context->error(errorAtEnd('$'), ReportContext::FORX0004, this); + return QString(); + } + + const QChar nextCh(input.at(i)); + if(nextCh.isDigit()) + retval.append(nextCh); + else + { + context->error(QtXmlPatterns::tr("In the replacement string, %1 must be " + "followed by at least one digit when not escaped.") + .arg(formatKeyword(QLatin1Char('$'))), + ReportContext::FORX0004, this); + return QString(); + } + + break; + } + case '\\': + { + ++i; + if(i == len) + { + /* error, we've reached the end. */; + context->error(errorAtEnd('\\'), ReportContext::FORX0004, this); + } + + const QChar nextCh(input.at(i)); + if(nextCh == QLatin1Char('\\') || nextCh == QLatin1Char('$')) + { + retval.append(ch); + break; + } + else + { + context->error(QtXmlPatterns::tr("In the replacement string, %1 can only be used to " + "escape itself or %2, not %3") + .arg(formatKeyword(QLatin1Char('\\'))) + .arg(formatKeyword(QLatin1Char('$'))) + .arg(formatKeyword(nextCh)), + ReportContext::FORX0004, this); + return QString(); + } + } + default: + retval.append(ch); + } + } + + return retval; +} + +Expression::Ptr ReplaceFN::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(PatternPlatform::compress(context)); + + if(me != this) + return me; + + if(m_operands.at(2)->is(IDStringValue)) + { + const int capt = captureCount(); + if(capt == -1) + return me; + else + m_replacementString = parseReplacement(captureCount(), context->dynamicContext()); + } + + return me; +} + +TokenizeFN::TokenizeFN() : PatternPlatform(2) +{ +} + +/** + * Used by QAbstractXmlForwardIterator. + */ +static inline bool qIsForwardIteratorEnd(const QString &item) +{ + return item.isNull(); +} + +Item TokenizeFN::mapToItem(const QString &subject, const DynamicContext::Ptr &) const +{ + return AtomicString::fromValue(subject); +} + +Item::Iterator::Ptr TokenizeFN::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const Item arg(m_operands.first()->evaluateSingleton(context)); + if(!arg) + return CommonValues::emptyIterator; + + const QString input(arg.stringValue()); + if(input.isEmpty()) + return CommonValues::emptyIterator; + + const QRegExp regExp(pattern(context)); + const QStringList result(input.split(regExp, QString::KeepEmptyParts)); + + return makeItemMappingIterator<Item>(ConstPtr(this), + makeListIterator(result), + DynamicContext::Ptr()); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qpatternmatchingfns_p.h b/src/xmlpatterns/functions/qpatternmatchingfns_p.h new file mode 100644 index 0000000..50bb450 --- /dev/null +++ b/src/xmlpatterns/functions/qpatternmatchingfns_p.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_PatternMatchingFNs_H +#define Patternist_PatternMatchingFNs_H + +#include "qpatternplatform_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#string.match">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 7.6 AtomicString Functions that Use Pattern Matching</a>. + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function <tt>fn:matches()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class MatchesFN : public PatternPlatform + { + public: + MatchesFN(); + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:replace()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class ReplaceFN : public PatternPlatform + { + public: + ReplaceFN(); + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + /** + * Overridden to attempt to pre-compile the replacement string. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + private: + /** + * @short Centralizes the translation string. + */ + static inline QString errorAtEnd(const char ch); + + /** + * Reads the string in the third argument and converts it to a a QRegExp compatible + * replacement string, containing sub-group references and so forth. + */ + QString parseReplacement(const int captureCount, + const DynamicContext::Ptr &context) const; + + QString m_replacementString; + }; + + /** + * @short Implements the function <tt>fn:tokenize()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class TokenizeFN : public PatternPlatform + { + public: + TokenizeFN(); + inline Item mapToItem(const QString &subject, const DynamicContext::Ptr &) const; + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + + private: + typedef QExplicitlySharedDataPointer<const TokenizeFN> ConstPtr; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qpatternplatform.cpp b/src/xmlpatterns/functions/qpatternplatform.cpp new file mode 100644 index 0000000..0052a07 --- /dev/null +++ b/src/xmlpatterns/functions/qpatternplatform.cpp @@ -0,0 +1,300 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QHash> + +#include "qpatternistlocale_p.h" + +#include "qpatternplatform_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +namespace QPatternist +{ + /** + * @short Used internally by PatternPlatform and describes + * a flag that affects how a pattern is treated. + * + * The member variables aren't declared @c const, in order + * to make the synthesized assignment operator and copy constructor work. + * + * @ingroup Patternist_utils + * @author Frans Englich <fenglich@trolltech.com> + */ + class PatternFlag + { + public: + typedef QHash<QChar, PatternFlag> Hash; + + inline PatternFlag() : flag(PatternPlatform::NoFlags) + { + } + + inline PatternFlag(const PatternPlatform::Flag opt, + const QString &descr) : flag(opt), + description(descr) + { + } + + PatternPlatform::Flag flag; + QString description; + + static inline Hash flagDescriptions(); + }; +} + +static inline PatternFlag::Hash flagDescriptions() +{ + PatternFlag::Hash retval; + + retval.insert(QChar(QLatin1Char('s')), + PatternFlag(PatternPlatform::DotAllMode, + QtXmlPatterns::tr("%1 matches newline characters").arg(formatKeyword(QLatin1Char('.'))))); + + retval.insert(QChar(QLatin1Char('m')), + PatternFlag(PatternPlatform::MultiLineMode, + QtXmlPatterns::tr("%1 and %2 match the start and end of a line.") + .arg(formatKeyword(QLatin1Char('^'))) + .arg(formatKeyword(QLatin1Char('$'))))); + + retval.insert(QChar(QLatin1Char('i')), + PatternFlag(PatternPlatform::CaseInsensitive, + QtXmlPatterns::tr("Matches are case insensitive"))); + + retval.insert(QChar(QLatin1Char('x')), + PatternFlag(PatternPlatform::SimplifyWhitespace, + QtXmlPatterns::tr("Whitespace characters are removed, except when they appear " + "in character classes"))); + + return retval; +} + +PatternPlatform::PatternPlatform(const qint8 flagsPosition) : m_compiledParts(NoPart), + m_flags(NoFlags), + m_flagsPosition(flagsPosition) +{ +} + +const QRegExp PatternPlatform::pattern(const DynamicContext::Ptr &context) const +{ + if(m_compiledParts == FlagsAndPattern) /* This is the most common case. */ + { + Q_ASSERT(m_pattern.isValid()); + return m_pattern; + } + + QRegExp retvalPattern; + Flags flags; + + /* Compile the flags, if necessary. */ + if(m_compiledParts.testFlag(FlagsPrecompiled)) + flags = m_flags; + else + { + const Expression::Ptr flagsOp(m_operands.value(m_flagsPosition)); + + if(flagsOp) + flags = parseFlags(flagsOp->evaluateSingleton(context).stringValue(), context); + else + flags = NoFlags; + } + + /* Compile the pattern, if necessary. */ + if(m_compiledParts.testFlag(PatternPrecompiled)) + retvalPattern = m_pattern; + else + { + retvalPattern = parsePattern(m_operands.at(1)->evaluateSingleton(context).stringValue(), + context); + + } + + applyFlags(flags, retvalPattern); + + Q_ASSERT(m_pattern.isValid()); + return retvalPattern; +} + +void PatternPlatform::applyFlags(const Flags flags, QRegExp &patternP) +{ + Q_ASSERT(patternP.isValid()); + if(flags == NoFlags) + return; + + if(flags & CaseInsensitive) + { + patternP.setCaseSensitivity(Qt::CaseInsensitive); + } + // TODO Apply the other flags, like 'x'. +} + +QRegExp PatternPlatform::parsePattern(const QString &patternP, + const DynamicContext::Ptr &context) const +{ + if(patternP == QLatin1String("(.)\\3") || + patternP == QLatin1String("\\3") || + patternP == QLatin1String("(.)\\2")) + { + context->error(QLatin1String("We don't want to hang infinitely on K2-MatchesFunc-9, " + "10 and 11. See Trolltech task 148505."), + ReportContext::FOER0000, this); + return QRegExp(); + } + + QString rewrittenPattern(patternP); + + /* We rewrite some well known patterns to QRegExp style here. Note that + * these character classes only works in the ASCII range, and fail for + * others. This support needs to be in QRegExp, since it's about checking + * QChar::category(). */ + rewrittenPattern.replace(QLatin1String("[\\i-[:]]"), QLatin1String("[a-zA-Z_]")); + rewrittenPattern.replace(QLatin1String("[\\c-[:]]"), QLatin1String("[a-zA-Z0-9_\\-\\.]")); + rewrittenPattern.replace(QLatin1String("\\i"), QLatin1String("[a-zA-Z:_]")); + rewrittenPattern.replace(QLatin1String("\\c"), QLatin1String("[a-zA-Z0-9:_\\-\\.]")); + rewrittenPattern.replace(QLatin1String("\\p{L}"), QLatin1String("[a-zA-Z]")); + rewrittenPattern.replace(QLatin1String("\\p{Lu}"), QLatin1String("[A-Z]")); + rewrittenPattern.replace(QLatin1String("\\p{Ll}"), QLatin1String("[a-z]")); + rewrittenPattern.replace(QLatin1String("\\p{Nd}"), QLatin1String("[0-9]")); + + QRegExp retval(rewrittenPattern); + + if(retval.isValid()) + return retval; + else + { + context->error(QtXmlPatterns::tr("%1 is an invalid regular expression pattern: %2") + .arg(formatExpression(patternP), retval.errorString()), + ReportContext::FORX0002, this); + return QRegExp(); + } +} + +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; +} + +Expression::Ptr PatternPlatform::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(FunctionCall::compress(context)); + if(me != this) + return me; + + if(m_operands.at(1)->is(IDStringValue)) + { + const DynamicContext::Ptr dynContext(context->dynamicContext()); + + m_pattern = parsePattern(m_operands.at(1)->evaluateSingleton(dynContext).stringValue(), + dynContext); + m_compiledParts |= PatternPrecompiled; + } + + const Expression::Ptr flagOperand(m_operands.value(m_flagsPosition)); + + if(!flagOperand) + { + m_flags = NoFlags; + m_compiledParts |= FlagsPrecompiled; + } + else if(flagOperand->is(IDStringValue)) + { + const DynamicContext::Ptr dynContext(context->dynamicContext()); + m_flags = parseFlags(flagOperand->evaluateSingleton(dynContext).stringValue(), + dynContext); + m_compiledParts |= FlagsPrecompiled; + } + + if(m_compiledParts == FlagsAndPattern) + applyFlags(m_flags, m_pattern); + + return me; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qpatternplatform_p.h b/src/xmlpatterns/functions/qpatternplatform_p.h new file mode 100644 index 0000000..ce0dbd4 --- /dev/null +++ b/src/xmlpatterns/functions/qpatternplatform_p.h @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_PatternPlatform_H +#define Patternist_PatternPlatform_H + +#include <QFlags> +#include <QRegExp> + +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Contains functionality for functions and expressions that + * uses regular expressions. + * + * @ingroup Patternist_utils + * @author Frans Englich <fenglich@trolltech.com> + */ + class PatternPlatform : public FunctionCall + { + public: + /** + * @see <a href="http://www.w3.org/TR/xpath-functions/#flags">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 7.6.1.1 Flags</a> + */ + enum Flag + { + /** + * No flags are set. Default behavior is used. + */ + NoFlags = 0, + + /** + * Flag @c s + */ + DotAllMode = 1, + + /** + * Flag @c m + */ + MultiLineMode = 2, + + /** + * Flag @c i + */ + CaseInsensitive = 4, + + /** + * Flag @c x + */ + SimplifyWhitespace = 8 + }; + typedef QFlags<Flag> Flags; + + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + /** + * Retrieves the pattern supplied in the arguments, taking care of compiling it, + * settings its flags, and everything else required for getting it ready to use. If an error + * occurs, an appropriate error is raised via @p context. + */ + const QRegExp pattern(const DynamicContext::Ptr &context) const; + + /** + * @returns the number of captures, also called parenthesized sub-expressions, the pattern has. + * + * If the pattern isn't precompiled, -1 is returned. + */ + inline int captureCount() const; + + protected: + /** + * @short This constructor is protected, because this class is supposed to be sub-classed. + * + * @param flagsPosition an index position specifying the operand containing the pattern + * flags. + */ + PatternPlatform(const qint8 flagsPosition); + + private: + /** + * Enum telling whether the flags, pattern, or both + * have been compiled at compile time. + */ + enum PreCompiledPart + { + NoPart = 0, + PatternPrecompiled = 1, + FlagsPrecompiled = 2, + FlagsAndPattern = PatternPrecompiled | FlagsPrecompiled + + }; + typedef QFlags<PreCompiledPart> PreCompiledParts; + + Q_DISABLE_COPY(PatternPlatform) + + Flags parseFlags(const QString &flags, + const DynamicContext::Ptr &context) const; + + QRegExp parsePattern(const QString &pattern, + const DynamicContext::Ptr &context) const; + + static void applyFlags(const Flags flags, QRegExp &pattern); + + /** + * The parts that have been pre-compiled at compile time. + */ + PreCompiledParts m_compiledParts; + Flags m_flags; + QRegExp m_pattern; + const qint8 m_flagsPosition; + }; + + inline int PatternPlatform::captureCount() const + { + if(m_compiledParts.testFlag(PatternPrecompiled)) + return m_pattern.numCaptures(); + else + return -1; + } + + Q_DECLARE_OPERATORS_FOR_FLAGS(PatternPlatform::Flags) +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qqnamefns.cpp b/src/xmlpatterns/functions/qqnamefns.cpp new file mode 100644 index 0000000..8074db8 --- /dev/null +++ b/src/xmlpatterns/functions/qqnamefns.cpp @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qanyuri_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonvalues_p.h" +#include "qpatternistlocale_p.h" +#include "qnodenamespaceresolver_p.h" +#include "qqnameconstructor_p.h" +#include "qqnamevalue_p.h" +#include "qatomicstring_p.h" +#include "qxpathhelper_p.h" + +#include "qqnamefns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item QNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item paramURI(m_operands.first()->evaluateSingleton(context)); + const QString paramQName(m_operands.last()->evaluateSingleton(context).stringValue()); + + QString ns; + if(paramURI) + ns = paramURI.stringValue(); + + if(!XPathHelper::isQName(paramQName)) + { + context->error(QtXmlPatterns::tr("%1 is an invalid %2").arg(formatData(paramQName), + formatType(context->namePool(), BuiltinTypes::xsQName)), + ReportContext::FOCA0002, this); + return Item(); + } + + QString prefix; + QString lname; + XPathHelper::splitQName(paramQName, prefix, lname); + const QXmlName n(context->namePool()->allocateQName(ns, lname, prefix)); + + if(ns.isEmpty()) + { + if(prefix.isEmpty()) + return toItem(QNameValue::fromValue(context->namePool(), n)); + else + { + context->error(QtXmlPatterns::tr( + "If the first argument is the empty sequence or " + "a zero-length string (no namespace), a prefix " + "cannot be specified. Prefix %1 was specified.") + .arg(formatKeyword(prefix)), + ReportContext::FOCA0002, this); + return Item(); /* Silence compiler warning. */ + } + } + else + return toItem(QNameValue::fromValue(context->namePool(), n)); +} + +Item ResolveQNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item itemName(m_operands.first()->evaluateSingleton(context)); + + if(!itemName) + return Item(); + + const NamespaceResolver::Ptr resolver(new NodeNamespaceResolver(m_operands.last()->evaluateSingleton(context))); + const QString strName(itemName.stringValue()); + const QXmlName name = QNameConstructor::expandQName<DynamicContext::Ptr, + ReportContext::FOCA0002, + ReportContext::FONS0004>(strName, + context, + resolver, + this); + + return toItem(QNameValue::fromValue(context->namePool(), name)); +} + +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 LocalNameFromQNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const QNameValue::Ptr arg(m_operands.first()->evaluateSingleton(context).as<QNameValue>()); + return arg ? toItem(AtomicString::fromValue(context->namePool()->stringForLocalName(arg->qName().localName()))) : Item(); +} + +Item NamespaceURIFromQNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const QNameValue::Ptr arg(m_operands.first()->evaluateSingleton(context).as<QNameValue>()); + return arg ? toItem(AnyURI::fromValue(context->namePool()->stringForNamespace(arg->qName().namespaceURI()))) : Item(); +} + +Item NamespaceURIForPrefixFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item prefixItem(m_operands.first()->evaluateSingleton(context)); + QXmlName::PrefixCode prefix; + + if(prefixItem) + prefix = context->namePool()->allocatePrefix(prefixItem.stringValue()); + else + prefix = StandardPrefixes::empty; + + const Item eleItem(m_operands.last()->evaluateSingleton(context)); + Q_ASSERT(eleItem); + + const QXmlName::NamespaceCode ns = eleItem.asNode().namespaceForPrefix(prefix); + + if(ns == NamespaceResolver::NoBinding) + { + /* This is a bit tricky. The default namespace is not considered an in-scope binding + * on a node, but the specification for this function do consider it a binding and therefore + * the empty string. */ + if(prefix == StandardPrefixes::empty) + return CommonValues::EmptyString; + else + return Item(); + } + else + return toItem(AnyURI::fromValue(context->namePool()->stringForNamespace(ns))); +} + +Item::Iterator::Ptr InScopePrefixesFN::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const Item e(m_operands.first()->evaluateSingleton(context)); + + const QVector<QXmlName> nbs(e.asNode().namespaceBindings()); + const int len = nbs.size(); + const NamePool::Ptr np(context->namePool()); + + QList<Item> result; + + for(int i = 0; i < len; ++i) + result.append(AtomicString::fromValue(np->stringForPrefix(nbs.at(i).prefix()))); + + return makeListIterator(result); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qqnamefns_p.h b/src/xmlpatterns/functions/qqnamefns_p.h new file mode 100644 index 0000000..6d22d06 --- /dev/null +++ b/src/xmlpatterns/functions/qqnamefns_p.h @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_QNameFNs_H +#define Patternist_QNameFNs_H + +#include "qfunctioncall_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#QName-funcs">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 11 Functions Related to QNames</a>. + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements the function <tt>fn:QXmlName()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class QNameFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:resolve-QXmlName()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class ResolveQNameFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:prefix-from-QXmlName()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class PrefixFromQNameFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:local-name-from-QXmlName()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class LocalNameFromQNameFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:local-name-from-QXmlName()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class NamespaceURIFromQNameFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:namespace-uri-from-QXmlName()</tt>. + * + * @author Frans Englich <fenglich@trolltech.com> + * @ingroup Patternist_functions + */ + class NamespaceURIForPrefixFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:in-scope-prefixes()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class InScopePrefixesFN : public FunctionCall + { + public: + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qresolveurifn.cpp b/src/xmlpatterns/functions/qresolveurifn.cpp new file mode 100644 index 0000000..6068e8f --- /dev/null +++ b/src/xmlpatterns/functions/qresolveurifn.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QUrl> + +#include "qanyuri_p.h" +#include "qliteral_p.h" +#include "qpatternistlocale_p.h" +#include "qatomicstring_p.h" + +#include "qresolveurifn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item ResolveURIFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item relItem(m_operands.first()->evaluateSingleton(context)); + + if(relItem) + { + const QString base(m_operands.last()->evaluateSingleton(context).stringValue()); + const QString relative(relItem.stringValue()); + + const QUrl baseURI(AnyURI::toQUrl<ReportContext::FORG0002, DynamicContext::Ptr>(base, context, this)); + const QUrl relativeURI(AnyURI::toQUrl<ReportContext::FORG0002, DynamicContext::Ptr>(relative, context, this)); + + return toItem(AnyURI::fromValue(baseURI.resolved(relativeURI))); + } + else + return Item(); +} + +Expression::Ptr ResolveURIFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + Q_ASSERT(m_operands.count() == 1 || m_operands.count() == 2); + + if(m_operands.count() == 1) + { + /* Our base URI is always well-defined. */ + m_operands.append(wrapLiteral(toItem(AnyURI::fromValue(context->baseURI())), context, this)); + } + + return FunctionCall::typeCheck(context, reqType); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qresolveurifn_p.h b/src/xmlpatterns/functions/qresolveurifn_p.h new file mode 100644 index 0000000..d49007a --- /dev/null +++ b/src/xmlpatterns/functions/qresolveurifn_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ResolveURIFN_H +#define Patternist_ResolveURIFN_H + +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function <tt>fn:resolve-uri()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class ResolveURIFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qsequencefns.cpp b/src/xmlpatterns/functions/qsequencefns.cpp new file mode 100644 index 0000000..f6d5391 --- /dev/null +++ b/src/xmlpatterns/functions/qsequencefns.cpp @@ -0,0 +1,353 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qdistinctiterator_p.h" +#include "qebvextractor_p.h" +#include "qemptysequence_p.h" +#include "qgenericsequencetype_p.h" +#include "qindexofiterator_p.h" +#include "qinsertioniterator_p.h" +#include "qinteger_p.h" +#include "qremovaliterator_p.h" +#include "qsequencegeneratingfns_p.h" +#include "qsubsequenceiterator_p.h" + +#include "qsequencefns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +bool BooleanFN::evaluateEBV(const DynamicContext::Ptr &context) const +{ + return m_operands.first()->evaluateEBV(context); +} + +Expression::Ptr BooleanFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + return EBVExtractor::typeCheck<FunctionCall>(context, reqType, this); +} + +Item::Iterator::Ptr IndexOfFN::evaluateSequence(const DynamicContext::Ptr &context) const +{ + return Item::Iterator::Ptr(new IndexOfIterator(m_operands.first()->evaluateSequence(context), + m_operands.at(1)->evaluateSingleton(context), + comparator(), context, + ConstPtr(this))); +} + +Expression::Ptr IndexOfFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + const Expression::Ptr me(FunctionCall::typeCheck(context, reqType)); + const ItemType::Ptr t1(m_operands.first()->staticType()->itemType()); + const ItemType::Ptr t2(m_operands.at(1)->staticType()->itemType()); + + if(*CommonSequenceTypes::Empty == *t1 || + *CommonSequenceTypes::Empty == *t2) + { + return EmptySequence::create(this, context); + } + else + { + prepareComparison(fetchComparator(t1, t2, context)); + return me; + } +} + +Item::Iterator::Ptr DistinctValuesFN::evaluateSequence(const DynamicContext::Ptr &context) const +{ + return Item::Iterator::Ptr(new DistinctIterator(m_operands.first()->evaluateSequence(context), + comparator(), + ConstPtr(this), + context)); +} + +Expression::Ptr DistinctValuesFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + const Expression::Ptr me(FunctionCall::typeCheck(context, reqType)); + const ItemType::Ptr t1(m_operands.first()->staticType()->itemType()); + + if(*CommonSequenceTypes::Empty == *t1) + return EmptySequence::create(this, context); + else if(!m_operands.first()->staticType()->cardinality().allowsMany()) + return m_operands.first(); + else if(BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t1)) + return me; + else + { + prepareComparison(fetchComparator(t1, t1, context)); + return me; + } +} + +SequenceType::Ptr DistinctValuesFN::staticType() const +{ + const SequenceType::Ptr t(m_operands.first()->staticType()); + return makeGenericSequenceType(t->itemType(), + t->cardinality().allowsMany() ? Cardinality::oneOrMore() + : Cardinality::exactlyOne()); +} + +Item::Iterator::Ptr InsertBeforeFN::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr target(m_operands.first()->evaluateSequence(context)); + const Item::Iterator::Ptr inserts(m_operands.at(2)->evaluateSequence(context)); + + xsInteger position = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()->toInteger(); + + if(position < 1) + position = 1; + + return Item::Iterator::Ptr(new InsertionIterator(target, position, inserts)); +} + +Item InsertBeforeFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return evaluateSequence(context)->next(); +} + +SequenceType::Ptr InsertBeforeFN::staticType() const +{ + const SequenceType::Ptr t1(m_operands.first()->staticType()); + const SequenceType::Ptr t2(m_operands.last()->staticType()); + + return makeGenericSequenceType(t1->itemType() | t2->itemType(), + t1->cardinality() + t2->cardinality()); +} + +Item::Iterator::Ptr RemoveFN::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const xsInteger pos = m_operands.last()->evaluateSingleton(context).as<Numeric>()->toInteger(); + Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context)); + + if(pos < 1) + return it; + + return Item::Iterator::Ptr(new RemovalIterator(it, pos)); +} + +Item RemoveFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const xsInteger pos = m_operands.last()->evaluateSingleton(context).as<Numeric>()->toInteger(); + if(pos <= 1) + return Item(); + + return m_operands.first()->evaluateSingleton(context); +} + +SequenceType::Ptr RemoveFN::staticType() const +{ + const SequenceType::Ptr opType(m_operands.first()->staticType()); + const Cardinality c(opType->cardinality()); + + if(c.minimum() == 0) + return makeGenericSequenceType(opType->itemType(), c); + else + { + return makeGenericSequenceType(opType->itemType(), + Cardinality::fromRange(c.minimum() - 1, + c.maximum())); + } +} + +Item::Iterator::Ptr ReverseFN::evaluateSequence(const DynamicContext::Ptr &context) const +{ + return m_operands.first()->evaluateSequence(context)->toReversed(); +} + +Expression::Ptr ReverseFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + if(m_operands.first()->staticType()->cardinality().allowsMany()) + return FunctionCall::typeCheck(context, reqType); + else + return m_operands.first()->typeCheck(context, reqType); +} + +SequenceType::Ptr ReverseFN::staticType() const +{ + return m_operands.first()->staticType(); +} + +SubsequenceFN::SubsequenceFN() : m_hasTypeChecked(false) +{ +} + +Expression::Ptr SubsequenceFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + m_hasTypeChecked = true; + return FunctionCall::typeCheck(context, reqType); +} + +Item::Iterator::Ptr SubsequenceFN::evaluateSequence(const DynamicContext::Ptr &context) const +{ + Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context)); + + xsInteger startingLoc = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()->round()->toInteger(); + xsInteger length = -1; + + if(m_operands.count() == 3) + { + length = m_operands.last()->evaluateSingleton(context).as<Numeric>()->toInteger(); + + if(startingLoc + length < 1 || (startingLoc > (startingLoc + length))) + return CommonValues::emptyIterator; + } + + /* F&O, 15.1.10, "If $startingLoc is zero or negative, the + * subsequence includes items from the beginning of the $sourceSeq." */ + if(startingLoc < 1) + startingLoc = 1; + + if(length < 1 && length != -1) + return CommonValues::emptyIterator; + else + return Item::Iterator::Ptr(new SubsequenceIterator(it, startingLoc, length)); +} + +Item SubsequenceFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return evaluateSequence(context)->next(); +} + +Expression::Ptr SubsequenceFN::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(FunctionCall::compress(context)); + if(me != this) + return me; + + const Expression::Ptr lenArg(m_operands.value(2)); + if(lenArg && lenArg->isEvaluated()) + { + const xsInteger length = lenArg->as<Literal>()->item().as<Numeric>()->round()->toInteger(); + + if(length <= 0) + return EmptySequence::create(this, context); + } + + return me; +} + +SequenceType::Ptr SubsequenceFN::staticType() const +{ + const SequenceType::Ptr opType(m_operands.first()->staticType()); + const Cardinality opCard(opType->cardinality()); + + /* Optimization: we can do much stronger inference here. If the length is a + * constant, we can constrain the range at least upwards of the + * cardinality, for instance. */ + + /* The subsequence(expr, 1, 1), add empty-sequence() to the static type. + * + * Note that we cannot do all these inferences before we've typechecked our + * operands. The only known case of where our staticType() is called before + * typeCheck() is through xmlpatternsview, although it wouldn't be + * surprising if the more exotic paths can achieve that too. + */ + if(m_hasTypeChecked && + m_operands.at(1)->isEvaluated() && + m_operands.count() == 3 && + m_operands.at(2)->isEvaluated() && + m_operands.at(1)->as<Literal>()->item().as<Numeric>()->round()->toInteger() == 1 && + m_operands.at(2)->as<Literal>()->item().as<Numeric>()->round()->toInteger() == 1) + { + return makeGenericSequenceType(opType->itemType(), + opCard.toWithoutMany()); + } + else + { + return makeGenericSequenceType(opType->itemType(), + opCard | Cardinality::zeroOrOne()); + } +} + +Expression::Ptr DocFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + /* See the doxygen documentation for this function for the explanation + * to why this implementation is here, as opposed to in + * qsequencegeneratingfns.cpp. */ + + Q_ASSERT(context); + + prepareStaticBaseURI(context); + + const Expression::Ptr uriOp(m_operands.first()); + + if(!uriOp->isEvaluated()) + return Expression::Ptr(FunctionCall::typeCheck(context, reqType)); + + const Item uriItem(uriOp->evaluateSingleton(context->dynamicContext())); + + if(!uriItem) + return EmptySequence::create(this, context)->typeCheck(context, reqType); // TODO test this + + /* These two lines were previously in a separate function but are now duplicated + * in DocFN::evaluateSingleton(), as part of a workaround for solaris-cc-64. */ + const QUrl mayRela(AnyURI::toQUrl<ReportContext::FODC0005>(uriItem.stringValue(), context, this)); + const QUrl uri(context->resolveURI(mayRela, staticBaseURI())); + + /* The URI is supplied statically, so, let's try to be clever. */ + Q_ASSERT_X(context->resourceLoader(), Q_FUNC_INFO, + "No resource loader is set in the StaticContext."); + m_type = context->resourceLoader()->announceDocument(uri, ResourceLoader::MayUse); + + if(m_type) + { + Q_ASSERT(CommonSequenceTypes::ZeroOrOneDocumentNode->matches(m_type)); + return Expression::Ptr(FunctionCall::typeCheck(context, reqType)); + } + else + { + context->error(QtXmlPatterns::tr("It will not be possible to retrieve %1.").arg(formatURI(uri)), + ReportContext::FODC0002, this); + return Expression::Ptr(); + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qsequencefns_p.h b/src/xmlpatterns/functions/qsequencefns_p.h new file mode 100644 index 0000000..3f79a5f --- /dev/null +++ b/src/xmlpatterns/functions/qsequencefns_p.h @@ -0,0 +1,338 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_SequenceFNs_H +#define Patternist_SequenceFNs_H + +#include "qatomiccomparator_p.h" +#include "qcomparisonplatform_p.h" +#include "qliteral_p.h" +#include "qfunctioncall_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#general-seq-funcs">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 15.1 General Functions and Operators on Sequences</a>. + * + * @todo document that some functions have both eval funcs implented. + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function <tt>fn:boolean()</tt>. + * + * @see EBVExtractor + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class BooleanFN : public FunctionCall + { + public: + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + + /** + * If @p reqType is CommonSequenceTypes::EBV, the type check of + * the operand is returned. Hence, this removes redundant calls + * to <tt>fn:boolean()</tt>. + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + }; + + /** + * @short Implements the function <tt>fn:index-of()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class IndexOfFN : public FunctionCall, + public ComparisonPlatform<IndexOfFN, false> + { + public: + inline IndexOfFN() : ComparisonPlatform<IndexOfFN, false>() + { + } + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + inline AtomicComparator::Operator operatorID() const + { + return AtomicComparator::OperatorEqual; + } + }; + + /** + * @short Implements the functions <tt>fn:exists()</tt> and <tt>fn:empty()</tt>. + * + * Existence is a template value class. Appropriate implementations are achieved + * by instantiating it with either IDExistsFN or IDEmptyFN. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + template<const Expression::ID Id> + class Existence : public FunctionCall + { + public: + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const + { + if(Id == IDExistsFN) + return !m_operands.first()->evaluateSequence(context)->isEmpty(); + else + return m_operands.first()->evaluateSequence(context)->isEmpty(); + } + + /** + * Attempts to rewrite to @c false or @c true by looking at the static + * cardinality of its operand. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context) + { + Q_ASSERT(Id == IDExistsFN || Id == IDEmptyFN); + const Expression::Ptr me(FunctionCall::compress(context)); + + if(me != this) + return me; + + const Cardinality myCard((Id == IDExistsFN) ? Cardinality::oneOrMore() : Cardinality::empty()); + + const Cardinality card(m_operands.first()->staticType()->cardinality()); + if(myCard.isMatch(card)) + { /* Since the dynamic type always is narrower than the static type or equal, and that the + static type is in scope, it means we will always be true. */ + return wrapLiteral(CommonValues::BooleanTrue, context, this); + } + else + { + /* Is it even possible to hit? */ + if(myCard.canMatch(card)) + { + return me; + } + else + { /* We can never hit. */ + return wrapLiteral(CommonValues::BooleanFalse, context, this); + } + } + } + }; + + /** + * @short Implements the function <tt>fn:distinct-values()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class DistinctValuesFN : public FunctionCall, + public ComparisonPlatform<IndexOfFN, false> + { + public: + inline DistinctValuesFN() : ComparisonPlatform<IndexOfFN, false>() + { + } + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + /** + * Performs necessary type checks, but also implements the optimization + * of rewriting to its operand if the operand's cardinality is zero-or-one + * or exactly-one. + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + /** + * @returns a type whose item type is the type of the first operand, and + * a cardinality which is non-empty if the first operand's type is non-empty + * and allows exactly-one. The latter is needed for operands which has the + * cardinality 2+, since distinct-values possibly removes items from the + * source sequence. + */ + virtual SequenceType::Ptr staticType() const; + + protected: + inline AtomicComparator::Operator operatorID() const + { + return AtomicComparator::OperatorEqual; + } + }; + + /** + * @short Implements the function <tt>fn:insert-before()</tt>. + * + * @todo docs, explain why evaluateSequence and evaluateSingleton is implemented + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class InsertBeforeFN : public FunctionCall + { + public: + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + /** + * Implements the static enferences rules. The function's static item type + * is the union type of the first and third argument, and the cardinality is + * the cardinalities of the two operands added together. For example, + * insert-before((1, "str"), 1, xs:double(0)) has the static type xs:anyAtomicType+. + * + * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_insert_before">XQuery 1.0 + * and XPath 2.0 Formal Semantics, 7.2.15 The fn:insert-before function</a> + */ + virtual SequenceType::Ptr staticType() const; + }; + + /** + * @short Implements the function <tt>fn:remove()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class RemoveFN : public FunctionCall + { + public: + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + /** + * Implements the static enferences rules, "Since one item may be removed + * from the sequence, the resulting type is made optional:" + * + * <tt>statEnv |- (FN-URI,"remove")(Type, Type1) : prime(Type) * quantifier(Type)?</tt> + * + * However, because Patternist's type system is more fine grained than Formal Semantics, + * the sequence isn't made optional. Instead its minimum length is reduced with one. + * + * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_remove">XQuery 1.0 + * and XPath 2.0 Formal Semantics, 7.2.11 The fn:remove function</a> + */ + virtual SequenceType::Ptr staticType() const; + }; + + /** + * @short Implements the function <tt>fn:reverse()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class ReverseFN : public FunctionCall + { + public: + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + /** + * Formally speaking, the type inference is: + * +@verbatim +statEnv |- (FN-URI,"reverse")(Type) : prime(Type) * quantifier(Type) +@endverbatim + * + * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_reverse">XQuery 1.0 + * and XPath 2.0 Formal Semantics, 7.2.12 The fn:reverse function</a> + * @returns the static type of the function's first argument. + */ + virtual SequenceType::Ptr staticType() const; + }; + + /** + * @short Implements the function <tt>fn:subsequence()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + * @todo Type inference can be made stronger for this function + */ + class SubsequenceFN : public FunctionCall + { + public: + SubsequenceFN(); + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + /** + * This function implements rewrites the SubsequenceFN instance into an + * empty sequence if its third argument, the sequence length argument, is + * evaluated and is effectively equal or less than zero. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + /** + * Partially implements the static type inference rules. + * + * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_subsequence">XQuery 1.0 + * and XPath 2.0 Formal Semantics, 7.2.13 The fn:subsequence function</a> + */ + virtual SequenceType::Ptr staticType() const; + + private: + bool m_hasTypeChecked; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qsequencegeneratingfns.cpp b/src/xmlpatterns/functions/qsequencegeneratingfns.cpp new file mode 100644 index 0000000..c77a3e7 --- /dev/null +++ b/src/xmlpatterns/functions/qsequencegeneratingfns.cpp @@ -0,0 +1,304 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QStack> +#include <QStringList> + +#include "qanyuri_p.h" +#include "qboolean_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qemptysequence_p.h" +#include "qitemmappingiterator_p.h" +#include "qnodesort_p.h" +#include "qpatternistlocale_p.h" +#include "private/qxmlutils_p.h" + +#include "qsequencegeneratingfns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +IdFN::IdFN() : m_hasCreatedSorter(false) +{ +} + +Item IdFN::mapToItem(const QString &id, + const IDContext &context) const +{ + return context.second->elementById(context.first->namePool()->allocateQName(QString(), id)); +} + +/** + * @short Helper class for StringSplitter + * + * Needed by the QAbstractXmlForwardIterator sub-class. + * + * @relates StringSplitter + */ +template<> +bool qIsForwardIteratorEnd(const QString &unit) +{ + return unit.isNull(); +} + +/** + * @short Helper class for IdFN. + * + * StringSplitter takes an Iterator which delivers strings of this kind: + * + * "a", "b c", "%invalidNCName", " ", "d" + * + * and we deliver instead: + * + * "a", "b", "c", "d" + * + * That is, we: + * - Remove invalid @c NCName + * - Split IDREFs into individual NCNames + * + * @author Frans Englich + */ +class StringSplitter : public QAbstractXmlForwardIterator<QString> +{ +public: + StringSplitter(const Item::Iterator::Ptr &source); + virtual QString next(); + virtual QString current() const; + virtual qint64 position() const; +private: + QString loadNext(); + const Item::Iterator::Ptr m_source; + QStack<QString> m_buffer; + QString m_current; + qint64 m_position; + bool m_sourceAtEnd; +}; + +StringSplitter::StringSplitter(const Item::Iterator::Ptr &source) : m_source(source) + , m_position(0) + , m_sourceAtEnd(false) +{ + Q_ASSERT(m_source); + m_buffer.push(loadNext()); +} + +QString StringSplitter::next() +{ + /* We also check m_position, we want to load on our first run. */ + if(!m_buffer.isEmpty()) + { + ++m_position; + m_current = m_buffer.pop(); + return m_current; + } + else if(m_sourceAtEnd) + { + m_current.clear(); + m_position = -1; + return QString(); + } + + return loadNext(); +} + +QString StringSplitter::loadNext() +{ + const Item sourceNext(m_source->next()); + + if(sourceNext.isNull()) + { + m_sourceAtEnd = true; + /* We might have strings in m_buffer, let's empty it. */ + return next(); + } + + const QStringList candidates(sourceNext.stringValue().simplified().split(QLatin1Char(' '))); + const int count = candidates.length(); + + for(int i = 0; i < count; ++i) + { + const QString &at = candidates.at(i); + + if(QXmlUtils::isNCName(at)) + m_buffer.push(at); + } + + /* So, now we have populated m_buffer, let's start from the beginning. */ + return next(); +} + +QString StringSplitter::current() const +{ + return m_current; +} + +qint64 StringSplitter::position() const +{ + return m_position; +} + +Item::Iterator::Ptr IdFN::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr idrefs(m_operands.first()->evaluateSequence(context)); + const Item node(m_operands.last()->evaluateSingleton(context)); + + checkTargetNode(node.asNode(), context, ReportContext::FODC0001); + + return makeItemMappingIterator<Item, + QString, + IdFN::ConstPtr, + IDContext>(ConstPtr(this), + StringSplitter::Ptr(new StringSplitter(idrefs)), + qMakePair(context, node.asNode().model())); +} + +Expression::Ptr IdFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + if(m_hasCreatedSorter) + return FunctionCall::typeCheck(context, reqType); + else + { + const Expression::Ptr newMe(new NodeSortExpression(Expression::Ptr(this))); + context->wrapExpressionWith(this, newMe); + m_hasCreatedSorter = true; + return newMe->typeCheck(context, reqType); + } +} + +Item::Iterator::Ptr IdrefFN::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr ids(m_operands.first()->evaluateSequence(context)); + + Item mId(ids->next()); + if(!mId) + return CommonValues::emptyIterator; + + const Item node(m_operands.last()->evaluateSingleton(context)); + checkTargetNode(node.asNode(), context, ReportContext::FODC0001); + + return CommonValues::emptyIterator; /* TODO Haven't implemented further. */ +} + +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; +} + +SequenceType::Ptr DocFN::staticType() const +{ + if(m_type) + return m_type; + else + return CommonSequenceTypes::ZeroOrOneDocumentNode; +} + +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); +} + +Item::Iterator::Ptr CollectionFN::evaluateSequence(const DynamicContext::Ptr &context) const +{ + // TODO resolve with URI resolve + if(m_operands.isEmpty()) + { + // TODO check default collection + context->error(QtXmlPatterns::tr("The default collection is undefined"), + ReportContext::FODC0002, this); + return CommonValues::emptyIterator; + } + else + { + const Item itemURI(m_operands.first()->evaluateSingleton(context)); + + if(itemURI) + { + const QUrl uri(AnyURI::toQUrl<ReportContext::FODC0004>(itemURI.stringValue(), context, this)); + + // TODO 2. Resolve against static context base URI(store base URI at compile time) + context->error(QtXmlPatterns::tr("%1 cannot be retrieved").arg(formatResourcePath(uri)), + ReportContext::FODC0004, this); + return CommonValues::emptyIterator; + } + else + { + /* This is out default collection currently, */ + return CommonValues::emptyIterator; + } + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qsequencegeneratingfns_p.h b/src/xmlpatterns/functions/qsequencegeneratingfns_p.h new file mode 100644 index 0000000..881a4d9 --- /dev/null +++ b/src/xmlpatterns/functions/qsequencegeneratingfns_p.h @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_SequenceGeneratingFNs_H +#define Patternist_SequenceGeneratingFNs_H + +#include "qanyuri_p.h" +#include "qcontextnodechecker_p.h" +#include "qstaticbaseuricontainer_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#fns-that-generate-sequences">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 15.5 Functions and Operators that Generate Sequences</a>. + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function <tt>fn:id()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class IdFN : public ContextNodeChecker + { + public: + IdFN(); + typedef QPair<DynamicContext::Ptr, const QAbstractXmlNodeModel *> IDContext; + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + + inline Item mapToItem(const QString &id, + const IDContext &context) const; + + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + private: + typedef QExplicitlySharedDataPointer<const IdFN> ConstPtr; + bool m_hasCreatedSorter; + }; + + /** + * @short Implements the function <tt>fn:idref()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class IdrefFN : public ContextNodeChecker + { + public: + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:doc()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class DocFN : public StaticBaseUriContainer + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + /** + * The implementation of this function is placed in a different compilation unit, + * namely qsequencefns.cpp, to workaround a compiler bug on + * solaris-cc-64, suspected to be related to the instantiation of QUrl::toQUrl(). + * + * @see <a + * href="http://onesearch.sun.com/search/onesearch/index.jsp?qt=6532605&site=sunsolve&otf=ss&col=support-sunsolve&otf=sunsolve&site=ss&col=search-sunsolve">Sun, + * multiply-defined label for template instance, bug 6532605</a> + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + virtual SequenceType::Ptr staticType() const; + + private: + SequenceType::Ptr m_type; + }; + + /** + * @short Implements the function <tt>fn:doc-available()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class DocAvailableFN : public StaticBaseUriContainer + { + public: + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:collection()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class CollectionFN : public FunctionCall + { + public: + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qstaticbaseuricontainer_p.h b/src/xmlpatterns/functions/qstaticbaseuricontainer_p.h new file mode 100644 index 0000000..ab21f24 --- /dev/null +++ b/src/xmlpatterns/functions/qstaticbaseuricontainer_p.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_StaticBaseUriContainer_H +#define Patternist_StaticBaseUriContainer_H + +#include <QUrl> + +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for functions that needs to + * store the static base URI for use at runtime. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class StaticBaseUriContainer : public FunctionCall + { + protected: + inline StaticBaseUriContainer() + { + } + + inline void prepareStaticBaseURI(const StaticContext::Ptr &context) + { + m_staticBaseURI = context->baseURI(); + } + + inline const QUrl &staticBaseURI() const + { + return m_staticBaseURI; + } + + /** + * Calls prepareStaticBaseURI(), and return the return value of + * FunctionCall::typeCheck(), forwarding the arguments. + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) + { + prepareStaticBaseURI(context); + return FunctionCall::typeCheck(context, reqType); + } + + private: + Q_DISABLE_COPY(StaticBaseUriContainer) + QUrl m_staticBaseURI; + }; +} + +QT_END_NAMESPACE +QT_END_HEADER +#endif diff --git a/src/xmlpatterns/functions/qstaticnamespacescontainer.cpp b/src/xmlpatterns/functions/qstaticnamespacescontainer.cpp new file mode 100644 index 0000000..d3dcf99 --- /dev/null +++ b/src/xmlpatterns/functions/qstaticnamespacescontainer.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstaticnamespacescontainer_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Expression::Ptr StaticNamespacesContainer::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + m_resolver = NamespaceResolver::Ptr(context->namespaceBindings()); + Q_ASSERT(m_resolver); + + return FunctionCall::typeCheck(context, reqType); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qstaticnamespacescontainer_p.h b/src/xmlpatterns/functions/qstaticnamespacescontainer_p.h new file mode 100644 index 0000000..3d21e15 --- /dev/null +++ b/src/xmlpatterns/functions/qstaticnamespacescontainer_p.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_StaticNamespacesContainer_H +#define Patternist_StaticNamespacesContainer_H + +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A helper subclass that stores a NamespaceResolver for the static + * namespaces. + * + * This is used by functionality which needs to resolve names against the + * statically known namespaces, at runtime. A good example of this is @c + * function-available(). + * + * The resolver is accessed through staticNamespaces(), which will be + * available after the typeCheck() stage. + * + * This class must be subclassed. + * + * @author Frans Englich <fenglich@trolltech.com> + * @ingroup Patternist_functions + */ + class StaticNamespacesContainer : public FunctionCall + { + public: + /** + * Reimplemented to store data from the @p context. + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + protected: + /** + * Before typeCheck(), behavior of this function is undefined. After + * typeCheck(), this function guarantees to return a valid pointer. + */ + inline const NamespaceResolver::Ptr &staticNamespaces() const + { + Q_ASSERT(m_resolver); + return m_resolver; + } + + /** + * This constructor only exists to ensure this class is subclassed. + */ + inline StaticNamespacesContainer() + { + } + + private: + NamespaceResolver::Ptr m_resolver; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qstringvaluefns.cpp b/src/xmlpatterns/functions/qstringvaluefns.cpp new file mode 100644 index 0000000..d57dd4c --- /dev/null +++ b/src/xmlpatterns/functions/qstringvaluefns.cpp @@ -0,0 +1,373 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstractfloat_p.h" +#include "qatomicstring_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qinteger_p.h" +#include "qliteral_p.h" +#include "qpatternistlocale_p.h" +#include "qschemanumeric_p.h" + +#include "qstringvaluefns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item ConcatFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Expression::List::const_iterator end(m_operands.constEnd()); + Expression::List::const_iterator it(m_operands.constBegin()); + QString result; + + for(; it != end; ++it) + { + Item item((*it)->evaluateSingleton(context)); + + if(item) + result += item.stringValue(); + } + + return AtomicString::fromValue(result); +} + +Item StringJoinFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context)); + Q_ASSERT(it); + Item current(it->next()); + + if(!current) /* Exit early, don't evaluate the separator. */ + return CommonValues::EmptyString; + + QString result; + QString separator; + const Item isep(m_operands.at(1)->evaluateSingleton(context)); + + if(isep) + separator = isep.stringValue(); + + while(true) + { + result += current.stringValue(); + current = it->next(); + + if(!current) + break; + + result += separator; + } + + return result.isEmpty() + ? toItem(CommonValues::EmptyString) + : toItem(AtomicString::fromValue(result)); +} + +Expression::Ptr StringJoinFN::compress(const StaticContext::Ptr &context) +{ + if(m_operands.first()->staticType()->cardinality().allowsMany()) + return FunctionCall::compress(context); + else + { + if(m_operands.first()->is(IDEmptySequence)) + return wrapLiteral(CommonValues::EmptyString, context, this); + else + return m_operands.first()->compress(context); + } +} + +Item SubstringFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + Item item(m_operands.first()->evaluateSingleton(context)); + + if(!item) + return CommonValues::EmptyString; + + const QString str(item.stringValue()); + + const xsDouble dblStart = m_operands.at(1)->evaluateSingleton(context).as<Numeric>() + ->round()->toDouble(); + if(qIsNaN(dblStart)) + return CommonValues::EmptyString; + + /* XPath starts from 1, but C++ starts from 0. */ + xsInteger startingLoc = Double::fromValue(dblStart)->round()->toInteger() - 1; + + xsInteger length = 0; + if(m_operands.count() == 2) + length = str.length() - startingLoc; + else + { + const xsDouble dblLen = m_operands.at(2)->evaluateSingleton(context).as<Numeric>() + ->round()->toDouble(); + + if(qIsNaN(dblLen)) + return CommonValues::EmptyString; + + length = Double::fromValue(dblLen)->round()->toInteger(); + if(startingLoc > startingLoc + length) + return CommonValues::EmptyString; + } + + if(startingLoc < 0) + { + length = length + startingLoc; + startingLoc = 0; + } + + return AtomicString::fromValue(str.mid(startingLoc, length)); +} + +Item StringLengthFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item item(m_operands.first()->evaluateSingleton(context)); + + /* fn:string() is re-implemented "inline" here. */ + if(item) + return Integer::fromValue(item.stringValue().length()); + else + return CommonValues::IntegerZero; +} + +NormalizeUnicodeFN::NormalizeUnicodeFN() : m_normForm(QString::NormalizationForm_C) +{ +} + +Item NormalizeSpaceFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item arg(m_operands.first()->evaluateSingleton(context)); + + if(!arg) + return CommonValues::EmptyString; + + return toItem(AtomicString::fromValue(arg.stringValue().simplified())); +} + +Item NormalizeUnicodeFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item arg(m_operands.first()->evaluateSingleton(context)); + + if(!arg) + return CommonValues::EmptyString; + + int normForm; + + /* The second argument has been removed, if we've already determined the form. */ + if(m_operands.count() == 1) + normForm = m_normForm; + else + { + normForm = determineNormalizationForm(context); + if(normForm == -1) + return toItem(AtomicString::fromValue(arg.stringValue())); + } + + return AtomicString::fromValue(arg.stringValue().normalized( + static_cast<QString::NormalizationForm>(normForm))); +} + +Expression::Ptr NormalizeUnicodeFN::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(FunctionCall::compress(context)); + if(me != this) + return me; + + Q_ASSERT(m_operands.count() == 1 || m_operands.count() == 2); + + if(m_operands.count() == 1) + m_normForm = QString::NormalizationForm_C; + else if(m_operands.last()->is(IDStringValue)) + { + m_normForm = static_cast<QString::NormalizationForm>( + determineNormalizationForm(context->dynamicContext())); + + if(m_normForm == -1) + return m_operands.first(); + + /* Remove the operand since we don't need it anymore. */ + m_operands.removeLast(); + } + + return me; +} + +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 UpperCaseFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item item(m_operands.first()->evaluateSingleton(context)); + + if(!item) + return CommonValues::EmptyString; + + return AtomicString::fromValue(item.stringValue().toUpper()); +} + +Item LowerCaseFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item item(m_operands.first()->evaluateSingleton(context)); + + if(!item) + return CommonValues::EmptyString; + + return AtomicString::fromValue(item.stringValue().toLower()); +} + +Item TranslateFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item item(m_operands.first()->evaluateSingleton(context)); + + if(!item) + return CommonValues::EmptyString; + + const QString mapString(m_operands.at(1)->evaluateSingleton(context).stringValue()); + const QString arg(item.stringValue()); + + if(mapString.isEmpty()) + return AtomicString::fromValue(arg); + + const QString transString(m_operands.at(2)->evaluateSingleton(context).stringValue()); + const int transLen = transString.length(); + const int argLen = arg.length(); + + QString result; + result.reserve(argLen); + int outI = 0; + + for(int i = 0; i < argLen; ++i) + { + const QChar argCh(arg.at(i)); + const int mapPos = mapString.indexOf(argCh); + + if(mapPos == -1) + { + result[outI] = argCh; + ++outI; + continue; + } + else if(mapPos >= transLen) + continue; + + const QChar transCh(transString.at(mapPos)); + + if(transCh.isNull()) + continue; + + result[outI] = transCh; + ++outI; + } + + result.truncate(outI); + return AtomicString::fromValue(result); +} + +EncodeString::EncodeString(const QByteArray &excludeChars, + const QByteArray &includeChars) : m_excludeChars(excludeChars), + m_includeChars(includeChars) +{ +} + +Item EncodeString::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item item(m_operands.first()->evaluateSingleton(context)); + + if(!item) + return CommonValues::EmptyString; + + return AtomicString::fromValue(QString::fromAscii(QUrl::toPercentEncoding(item.stringValue(), + m_excludeChars, + m_includeChars).constData())); +} + +const char *const EncodeForURIFN::include = "#!*'()"; + +EncodeForURIFN::EncodeForURIFN() : EncodeString(QByteArray(), QByteArray::fromRawData(include, 6)) +{ +} + +const char *const IriToURIFN::exclude = "#-_!~*'();?@&=+$,[]/:%"; + +IriToURIFN::IriToURIFN() : EncodeString(QByteArray::fromRawData(exclude, 22), QByteArray()) +{ +} + +const char *const EscapeHtmlURIFN::include = "?&[]%"; +const char *const EscapeHtmlURIFN::exclude = " :;=@!./+*()-,#$'"; + +EscapeHtmlURIFN::EscapeHtmlURIFN() : EncodeString(QByteArray::fromRawData(exclude, 17), + QByteArray::fromRawData(include, 6)) +{ +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qstringvaluefns_p.h b/src/xmlpatterns/functions/qstringvaluefns_p.h new file mode 100644 index 0000000..b677d40 --- /dev/null +++ b/src/xmlpatterns/functions/qstringvaluefns_p.h @@ -0,0 +1,293 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_StringValueFNs_H +#define Patternist_StringValueFNs_H + +#include <QByteArray> + +#include "qfunctioncall_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#string-value-functions">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 7.4 Functions on AtomicString Values</a>. + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements the function <tt>fn:concat()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class ConcatFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:string-join()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class StringJoinFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + /** + * Optimization: when the cardinality of the sequence of items to join + * cannot be two or more, we have no effect and therefore rewrite + * ourselves to our first operand. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + }; + + /** + * @short Implements the function <tt>fn:substring()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class SubstringFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:string-length()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class StringLengthFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:normalize-space()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class NormalizeSpaceFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:normalize-unicode()</tt>. + * + * What perhaps can be said significant with the implementation, is that it + * attempts to determine the normalization form at compile time, in order to + * reduce string work at runtime. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class NormalizeUnicodeFN : public FunctionCall + { + public: + /** + * Initializes private data. + */ + NormalizeUnicodeFN(); + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + private: + int determineNormalizationForm(const DynamicContext::Ptr &context) const; + QString::NormalizationForm m_normForm; + }; + + /** + * @short Implements the function <tt>fn:upper-case()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class UpperCaseFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:lower-case()</tt>. + * + * @short Implements the function <tt>fn:concat()</tt>. + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class LowerCaseFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:translate()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class TranslateFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Provides functionality for encoding strings. Sub-classed by various + * function implementations. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class EncodeString : public FunctionCall + { + public: + /** + * Evaluates its first operand. If it is the empty sequence, an empty string + * is returned. Otherwise, the item's string value is returned percent encoded + * as specified in this class's constructor. + */ + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + protected: + /** + * Encodes its operand with QUrl::toPercentEncoding(), with @p includeChars as + * the characters to encode, and @p excludeChars as the characters to not encode. + */ + EncodeString(const QByteArray &excludeChars, const QByteArray &includeChars); + + private: + const QByteArray m_excludeChars; + const QByteArray m_includeChars; + }; + + /** + * @short Implements the function <tt>fn:encode-for-uri()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class EncodeForURIFN : public EncodeString + { + public: + /** + * Performs internal initialization. + */ + EncodeForURIFN(); + + private: + static const char *const include; + }; + + /** + * @short Implements the function <tt>fn:iri-to-uri()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class IriToURIFN : public EncodeString + { + public: + /** + * Performs internal initialization. + */ + IriToURIFN(); + + private: + static const char *const exclude; + }; + + /** + * @short Implements the function <tt>fn:escape-html-uri()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class EscapeHtmlURIFN : public EncodeString + { + public: + /** + * Performs internal initialization. + */ + EscapeHtmlURIFN(); + + private: + static const char *const include; + static const char *const exclude; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qsubstringfns.cpp b/src/xmlpatterns/functions/qsubstringfns.cpp new file mode 100644 index 0000000..301f56a --- /dev/null +++ b/src/xmlpatterns/functions/qsubstringfns.cpp @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qboolean_p.h" +#include "qcommonvalues_p.h" +#include "qliteral_p.h" +#include "qatomicstring_p.h" + +#include "qsubstringfns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item ContainsFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item op1(m_operands.first()->evaluateSingleton(context)); + QString str1; + + if(op1) + str1 = op1.stringValue(); + + const Item op2(m_operands.at(1)->evaluateSingleton(context)); + QString str2; + + if(op2) + str2 = op2.stringValue(); + + if(str2.isEmpty()) + return CommonValues::BooleanTrue; + + if(str1.isEmpty()) + return CommonValues::BooleanFalse; + + return Boolean::fromValue(str1.contains(str2, caseSensitivity())); +} + +Item StartsWithFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item op1(m_operands.first()->evaluateSingleton(context)); + QString str1; + + if(op1) + str1 = op1.stringValue(); + + const Item op2(m_operands.at(1)->evaluateSingleton(context)); + QString str2; + + if(op2) + str2 = op2.stringValue(); + + if(str2.isEmpty()) + return CommonValues::BooleanTrue; + + if(str1.isEmpty()) + return CommonValues::BooleanFalse; + + return Boolean::fromValue(str1.startsWith(str2, caseSensitivity())); +} + +Item EndsWithFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item op1(m_operands.first()->evaluateSingleton(context)); + QString str1; + + if(op1) + str1 = op1.stringValue(); + + const Item op2(m_operands.at(1)->evaluateSingleton(context)); + QString str2; + + if(op2) + str2 = op2.stringValue(); + + if(str2.isEmpty()) + return CommonValues::BooleanTrue; + + if(str1.isEmpty()) + return CommonValues::BooleanFalse; + + return Boolean::fromValue(str1.endsWith(str2, caseSensitivity())); +} + +Item SubstringBeforeFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item op1(m_operands.first()->evaluateSingleton(context)); + QString str1; + + if(op1) + str1 = op1.stringValue(); + + const Item op2(m_operands.at(1)->evaluateSingleton(context)); + QString str2; + + if(op2) + str2 = op2.stringValue(); + + const int pos = str1.indexOf(str2); + if(pos == -1) + return CommonValues::EmptyString; + + return AtomicString::fromValue(QString(str1.left(pos))); +} + +Item SubstringAfterFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item op1(m_operands.first()->evaluateSingleton(context)); + QString str1; + + if(op1) + str1 = op1.stringValue(); + + const Item op2(m_operands.at(1)->evaluateSingleton(context)); + QString str2; + + if(op2) + str2 = op2.stringValue(); + + if(str2.isEmpty()) + { + if(op1) + return op1; + else + return CommonValues::EmptyString; + } + + const int pos = str1.indexOf(str2); + + if(pos == -1) + return CommonValues::EmptyString; + + return AtomicString::fromValue(QString(str1.right(str1.length() - (pos + str2.length())))); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qsubstringfns_p.h b/src/xmlpatterns/functions/qsubstringfns_p.h new file mode 100644 index 0000000..2926764 --- /dev/null +++ b/src/xmlpatterns/functions/qsubstringfns_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_SubStringFNs_H +#define Patternist_SubStringFNs_H + +#include "qcomparescaseaware_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#substring.functions">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 7.5 Functions Based on Substring Matching</a>. + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function <tt>fn:contains()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class ContainsFN : public ComparesCaseAware + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:starts-with()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class StartsWithFN : public ComparesCaseAware + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:ends-with()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class EndsWithFN : public ComparesCaseAware + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:substring-before()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class SubstringBeforeFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; + + /** + * @short Implements the function <tt>fn:substring-after()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class SubstringAfterFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qsystempropertyfn.cpp b/src/xmlpatterns/functions/qsystempropertyfn.cpp new file mode 100644 index 0000000..edd413d --- /dev/null +++ b/src/xmlpatterns/functions/qsystempropertyfn.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qatomicstring_p.h" +#include "qqnameconstructor_p.h" + +#include "qsystempropertyfn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item SystemPropertyFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const QString lexQName(m_operands.first()->evaluateSingleton(context).stringValue()); + + const QXmlName name + (QNameConstructor::expandQName<DynamicContext::Ptr, + ReportContext::XTDE1390, + ReportContext::XTDE1390>(lexQName, + context, + staticNamespaces(), this)); + + return AtomicString::fromValue(retrieveProperty(name)); +} + +QString SystemPropertyFN::retrieveProperty(const QXmlName name) +{ + if(name.namespaceURI() != StandardNamespaces::xslt) + return QString(); + + switch(name.localName()) + { + case StandardLocalNames::version: + /* + * The supported XSL-T version. + * + * @see <a href="http://www.w3.org/TR/xslt20/#system-property">The Note paragraph + * at the very end of XSL Transformations (XSLT) Version 2.0, + * 16.6.5 system-property</a> + */ + return QString::number(1.20); + case StandardLocalNames::vendor: + return QLatin1String("Nokia Corporation and/or its subsidiary(-ies), a Nokia Company"); + case StandardLocalNames::vendor_url: + return QLatin1String("http://qtsoftware.com/"); + case StandardLocalNames::product_name: + return QLatin1String("QtXmlPatterns"); + case StandardLocalNames::product_version: + return QLatin1String("0.1"); + case StandardLocalNames::is_schema_aware: + /* Fallthrough. */ + case StandardLocalNames::supports_backwards_compatibility: + /* Fallthrough. */ + case StandardLocalNames::supports_serialization: + /* Fallthrough. */ + return QLatin1String("no"); + default: + return QString(); + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qsystempropertyfn_p.h b/src/xmlpatterns/functions/qsystempropertyfn_p.h new file mode 100644 index 0000000..3b12edb --- /dev/null +++ b/src/xmlpatterns/functions/qsystempropertyfn_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_SystemPropertyFN_H +#define Patternist_SystemPropertyFN_H + +#include "qstaticnamespacescontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements XSL-T 2.0's XPath function <tt>fn:system-property()</tt>. + * + * @see <a href="http://www.w3.org/TR/xslt20/#system-property">XSL Transformations + * (XSLT) Version 2.0, 16.6.5 system-property</a> + * @author Frans Englich <fenglich@trolltech.com> + * @ingroup Patternist_functions + */ + class SystemPropertyFN : public StaticNamespacesContainer + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + private: + /** + * Returns a string representation for @p property as defined + * for the system properties in "XSL Transformations (XSLT) + * Version 2.0, 16.6.5 system-property". Hence, this function + * handles only the properties specified in the XSL namespace, and returns + * an empty string if an unrecognized property is asked for. + */ + static QString retrieveProperty(const QXmlName name); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qtimezonefns.cpp b/src/xmlpatterns/functions/qtimezonefns.cpp new file mode 100644 index 0000000..1968ffb --- /dev/null +++ b/src/xmlpatterns/functions/qtimezonefns.cpp @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstractdatetime_p.h" +#include "qcontextfns_p.h" +#include "qdate_p.h" +#include "qschemadatetime_p.h" +#include "qdaytimeduration_p.h" +#include "qpatternistlocale_p.h" +#include "qschematime_p.h" + +#include "qtimezonefns_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item AdjustTimezone::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + enum + { + /** + * The maximum zone offset, @c PT14H, in milli seconds. + */ + MSecLimit = 14 * 60/*M*/ * 60/*S*/ * 1000/*ms*/ + }; + + + const Item arg(m_operands.first()->evaluateSingleton(context)); + if(!arg) + return Item(); + + QDateTime dt(arg.as<AbstractDateTime>()->toDateTime()); + // TODO DT dt.setDateOnly(false); + Q_ASSERT(dt.isValid()); + DayTimeDuration::Ptr tz; + + if(m_operands.count() == 2) + tz = DayTimeDuration::Ptr(m_operands.at(1)->evaluateSingleton(context).as<DayTimeDuration>()); + else + tz = context->implicitTimezone(); + + if(tz) + { + const MSecondCountProperty tzMSecs = tz->value(); + + if(tzMSecs % (1000 * 60) != 0) + { + context->error(QtXmlPatterns::tr("A zone offset must be in the " + "range %1..%2 inclusive. %3 is " + "out of range.") + .arg(formatData("-PT14H")) + .arg(formatData("PT14H")) + .arg(formatData(tz->stringValue())), + ReportContext::FODT0003, this); + return Item(); + } + else if(tzMSecs > MSecLimit || + tzMSecs < -MSecLimit) + { + context->error(QtXmlPatterns::tr("%1 is not a whole number of minutes.") + .arg(formatData(tz->stringValue())), + ReportContext::FODT0003, this); + return Item(); + } + + const SecondCountProperty tzSecs = tzMSecs / 1000; + + if(dt.timeSpec() == Qt::LocalTime) /* $arg has no time zone. */ + { + /* "If $arg does not have a timezone component and $timezone is not + * the empty sequence, then the result is $arg with $timezone as + * the timezone component." */ + //dt.setTimeSpec(QDateTime::Spec(QDateTime::OffsetFromUTC, tzSecs)); + dt.setUtcOffset(tzSecs); + Q_ASSERT(dt.isValid()); + return createValue(dt); + } + else + { + /* "If $arg has a timezone component and $timezone is not the empty sequence, + * then the result is an xs:dateTime value with a timezone component of + * $timezone that is equal to $arg." */ + dt = dt.toUTC(); + dt = dt.addSecs(tzSecs); + //dt.setTimeSpec(QDateTime::Spec(QDateTime::OffsetFromUTC, tzSecs)); + dt.setUtcOffset(tzSecs); + Q_ASSERT(dt.isValid()); + return createValue(dt); + } + } + else + { /* $timezone is the empty sequence. */ + if(dt.timeSpec() == Qt::LocalTime) /* $arg has no time zone. */ + { + /* "If $arg does not have a timezone component and $timezone is + * the empty sequence, then the result is $arg." */ + return arg; + } + else + { + /* "If $arg has a timezone component and $timezone is the empty sequence, + * then the result is the localized value of $arg without its timezone component." */ + dt.setTimeSpec(Qt::LocalTime); + return createValue(dt); + } + } +} + +Item AdjustDateTimeToTimezoneFN::createValue(const QDateTime &dt) const +{ + Q_ASSERT(dt.isValid()); + return DateTime::fromDateTime(dt); +} + +Item AdjustDateToTimezoneFN::createValue(const QDateTime &dt) const +{ + Q_ASSERT(dt.isValid()); + return Date::fromDateTime(dt); +} + +Item AdjustTimeToTimezoneFN::createValue(const QDateTime &dt) const +{ + Q_ASSERT(dt.isValid()); + return SchemaTime::fromDateTime(dt); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qtimezonefns_p.h b/src/xmlpatterns/functions/qtimezonefns_p.h new file mode 100644 index 0000000..a6373e4 --- /dev/null +++ b/src/xmlpatterns/functions/qtimezonefns_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_TimezoneFNs_H +#define Patternist_TimezoneFNs_H + +#include "qatomiccomparator_p.h" +#include "qfunctioncall_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * <a href="http://www.w3.org/TR/xpath-functions/#timezone.functions">XQuery 1.0 and + * XPath 2.0 Functions and Operators, 10.7 Timezone Adjustment on Dates and SchemaTime Values</a>. + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for classes implementing functions changing the timezone + * on values. + * + * It would be possible to implement this with the Curiously Recurring Template Pattern, in order + * to avoid the virtual call dispatching that is done via createValue(). However, these are not + * very hot code paths and evaluateSingleton() is quite large, which would lead to heavy code + * expansion. + * + * @see <a href="http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern">Curiously + * Recurring Template Pattern, Wikipedia, the free encyclopedia</a> + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class AdjustTimezone : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + protected: + virtual Item createValue(const QDateTime &dt) const = 0; + }; + + /** + * @short Implements the function <tt>fn:adjust-dateTime-to-timezone()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class AdjustDateTimeToTimezoneFN : public AdjustTimezone + { + protected: + virtual Item createValue(const QDateTime &dt) const; + }; + + /** + * @short Implements the function <tt>fn:adjust-dateTime-to-timezone()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class AdjustDateToTimezoneFN : public AdjustTimezone + { + protected: + virtual Item createValue(const QDateTime &dt) const; + }; + + /** + * @short Implements the function <tt>fn:adjust-time-to-timezone()</tt>. + * + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class AdjustTimeToTimezoneFN : public AdjustTimezone + { + protected: + virtual Item createValue(const QDateTime &dt) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qtracefn.cpp b/src/xmlpatterns/functions/qtracefn.cpp new file mode 100644 index 0000000..c7f193e --- /dev/null +++ b/src/xmlpatterns/functions/qtracefn.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qitemmappingiterator_p.h" +#include "qpatternistlocale_p.h" + +#include "qtracefn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +namespace QPatternist +{ + /** + * @short TraceCallback is a MappingCallback and takes care of + * the tracing of each individual item. + * + * Because Patternist must be thread safe, TraceFN creates a TraceCallback + * each time the function is evaluated. In other words, TraceFN, which is + * an Expression sub class, can't modify its members, but MappingCallback + * does not have this limitation since it's created on a per evaluation basis. + * + * @author Frans Englich <fenglich@trolltech.com> + */ + class TraceCallback : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer<TraceCallback> Ptr; + + inline TraceCallback(const QString &msg) : m_position(0), + m_msg(msg) + { + } + + /** + * 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; + } + + private: + xsInteger m_position; + const QString m_msg; + }; +} + +Item::Iterator::Ptr TraceFN::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const QString msg(m_operands.last()->evaluateSingleton(context).stringValue()); + + return makeItemMappingIterator<Item>(TraceCallback::Ptr(new TraceCallback(msg)), + m_operands.first()->evaluateSequence(context), + context); +} + +Item TraceFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const QString msg(m_operands.last()->evaluateSingleton(context).stringValue()); + const Item item(m_operands.first()->evaluateSingleton(context)); + + return TraceCallback::Ptr(new TraceCallback(msg))->mapToItem(item, context); +} + +SequenceType::Ptr TraceFN::staticType() const +{ + return m_operands.first()->staticType(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qtracefn_p.h b/src/xmlpatterns/functions/qtracefn_p.h new file mode 100644 index 0000000..667d5c2 --- /dev/null +++ b/src/xmlpatterns/functions/qtracefn_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_TraceFN_H +#define Patternist_TraceFN_H + +#include "qfunctioncall_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function <tt>fn:trace()</tt>. + * @ingroup Patternist_functions + * @author Frans Englich <fenglich@trolltech.com> + */ + class TraceFN : public FunctionCall + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + + /** + * Formally speaking, the type inference is: + * +@verbatim +statEnv |- (FN-URI,"trace")(Type) : prime(Type) * quantifier(Type) +@endverbatim + * + * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_reverse">XQuery 1.0 + * and XPath 2.0 Formal Semantics, 7.2.12 The fn:reverse function</a>, for + * an example of where the type inference is used + * @returns the static type of the function's first argument. + */ + virtual SequenceType::Ptr staticType() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qtypeavailablefn.cpp b/src/xmlpatterns/functions/qtypeavailablefn.cpp new file mode 100644 index 0000000..d120df8 --- /dev/null +++ b/src/xmlpatterns/functions/qtypeavailablefn.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qboolean_p.h" +#include "qqnameconstructor_p.h" + +#include "qtypeavailablefn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item TypeAvailableFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const QString lexQName(m_operands.first()->evaluateSingleton(context).stringValue()); + + const QXmlName name + (QNameConstructor::expandQName<DynamicContext::Ptr, + ReportContext::XTDE1428, + ReportContext::XTDE1428>(lexQName, + context, + staticNamespaces(), + this)); + + + return Boolean::fromValue(m_schemaTypeFactory->types().contains(name)); +} + +Expression::Ptr TypeAvailableFN::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + m_schemaTypeFactory = context->schemaDefinitions(); + return StaticNamespacesContainer::typeCheck(context, reqType); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qtypeavailablefn_p.h b/src/xmlpatterns/functions/qtypeavailablefn_p.h new file mode 100644 index 0000000..d37c306 --- /dev/null +++ b/src/xmlpatterns/functions/qtypeavailablefn_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_TypeAvailableFN_H +#define Patternist_TypeAvailableFN_H + +#include "qschematypefactory_p.h" +#include "qstaticnamespacescontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements XSL-T 2.0's XPath function <tt>fn:type-available()</tt>. + * + * @see <a href="http://www.w3.org/TR/xslt20/#function-function-available">XSL Transformations + * (XSLT) Version 2.0, 18.1.1 Testing Availability of Functions</a> + * @author Frans Englich <fenglich@trolltech.com> + * @ingroup Patternist_functions + */ + class TypeAvailableFN : public StaticNamespacesContainer + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + /** + * Reimplemented to store data from the @p context which is needed at runtime. + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + private: + SchemaTypeFactory::Ptr m_schemaTypeFactory; + }; + +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qunparsedentitypublicidfn.cpp b/src/xmlpatterns/functions/qunparsedentitypublicidfn.cpp new file mode 100644 index 0000000..269b81e --- /dev/null +++ b/src/xmlpatterns/functions/qunparsedentitypublicidfn.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qatomicstring_p.h" + +#include "qunparsedentitypublicidfn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item UnparsedEntityPublicIDFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + checkTargetNode(context->contextItem().asNode(), context, ReportContext::XTDE1380); + return AtomicString::fromValue(QString()); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qunparsedentitypublicidfn_p.h b/src/xmlpatterns/functions/qunparsedentitypublicidfn_p.h new file mode 100644 index 0000000..e9af810 --- /dev/null +++ b/src/xmlpatterns/functions/qunparsedentitypublicidfn_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_UnparsedEntityPublicID_H +#define Patternist_UnparsedEntityPublicID_H + +#include "qcontextnodechecker_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements XSL-T 2.0's XPath function <tt>fn:unparsed-entity-public-id()</tt>. + * + * @see <a href="http://www.w3.org/TR/xslt20/#function-unparsed-entity-uri">XSL Transformations + * (XSLT) Version 2.0, 16.6.3 unparsed-entity-public-id</a> + * @author Frans Englich <fenglich@trolltech.com> + * @ingroup Patternist_functions + */ + class UnparsedEntityPublicIDFN : public ContextNodeChecker + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qunparsedentityurifn.cpp b/src/xmlpatterns/functions/qunparsedentityurifn.cpp new file mode 100644 index 0000000..8058012 --- /dev/null +++ b/src/xmlpatterns/functions/qunparsedentityurifn.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qanyuri_p.h" + +#include "qunparsedentityurifn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item UnparsedEntityURIFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + checkTargetNode(context->contextItem().asNode(), context, ReportContext::XTDE1370); + return toItem(AnyURI::fromValue(QUrl())); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qunparsedentityurifn_p.h b/src/xmlpatterns/functions/qunparsedentityurifn_p.h new file mode 100644 index 0000000..7dcd69f --- /dev/null +++ b/src/xmlpatterns/functions/qunparsedentityurifn_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_UnparsedEntityURIFN_H +#define Patternist_UnparsedEntityURIFN_H + +#include "qcontextnodechecker_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements XSL-T 2.0's XPath function <tt>fn:unparsed-entity-uri()</tt>. + * + * @see <a href="http://www.w3.org/TR/xslt20/#function-unparsed-entity-uri">XSL Transformations + * (XSLT) Version 2.0, 16.6.2 unparsed-entity-uri</a> + * @author Frans Englich <fenglich@trolltech.com> + * @ingroup Patternist_functions + */ + class UnparsedEntityURIFN : public ContextNodeChecker + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qunparsedtextavailablefn.cpp b/src/xmlpatterns/functions/qunparsedtextavailablefn.cpp new file mode 100644 index 0000000..c092240 --- /dev/null +++ b/src/xmlpatterns/functions/qunparsedtextavailablefn.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qanyuri_p.h" + +#include "qunparsedtextavailablefn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +bool UnparsedTextAvailableFN::evaluateEBV(const DynamicContext::Ptr &context) const +{ + Q_ASSERT(m_operands.count() == 1 || m_operands.count() == 2); + const Item href(m_operands.first()->evaluateSingleton(context)); + if(!href) + return Item(); + + bool isValid = false; + const QUrl mayRela(AnyURI::toQUrl<ReportContext::XTDE1170>(href.stringValue(), + context, + this, + &isValid)); + + if(!isValid) + return false; + + const QUrl uri(context->resolveURI(mayRela, staticBaseURI())); + + /* fn:unparsed-text() will raise an error on this. */ + if(uri.hasFragment()) + return false; + + QString encoding; + + if(m_operands.count() == 2) + { + const Item encodingArg(m_operands.at(1)->evaluateSingleton(context)); + if(encodingArg) + encoding = encodingArg.stringValue(); + } + + Q_ASSERT(uri.isValid() && !uri.isRelative()); + return context->resourceLoader()->isUnparsedTextAvailable(uri, encoding); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qunparsedtextavailablefn_p.h b/src/xmlpatterns/functions/qunparsedtextavailablefn_p.h new file mode 100644 index 0000000..938a68a --- /dev/null +++ b/src/xmlpatterns/functions/qunparsedtextavailablefn_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_UnparsedTextAvailableFN_H +#define Patternist_UnparsedTextAvailableFN_H + +#include "qstaticbaseuricontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE +namespace QPatternist +{ + + /** + * @short Implements the function <tt>fn:unparsed-text-available()</tt>. + * + * @ingroup Patternist_functions + * @see <a href="http://www.w3.org/TR/xslt20/#unparsed-text">XSL + * Transformations (XSLT) Version 2.0, 16.2 unparsed-text</a> + * @author Frans Englich <fenglich@trolltech.com> + * @since 4.5 + */ + class UnparsedTextAvailableFN : public StaticBaseUriContainer + { + public: + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qunparsedtextfn.cpp b/src/xmlpatterns/functions/qunparsedtextfn.cpp new file mode 100644 index 0000000..0400c94 --- /dev/null +++ b/src/xmlpatterns/functions/qunparsedtextfn.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qanyuri_p.h" + +#include "qunparsedtextfn_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item UnparsedTextFN::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + Q_ASSERT(m_operands.count() == 1 || m_operands.count() == 2); + const Item href(m_operands.first()->evaluateSingleton(context)); + if(!href) + return Item(); + + const QUrl mayRela(AnyURI::toQUrl<ReportContext::XTDE1170>(href.stringValue(), + context, + this)); + + const QUrl uri(context->resolveURI(mayRela, staticBaseURI())); + + if(uri.hasFragment()) + { + context->error(QtXmlPatterns::tr("The URI cannot have a fragment"), + ReportContext::XTDE1170, this); + } + + QString encoding; + + if(m_operands.count() == 2) + { + const Item encodingArg(m_operands.at(1)->evaluateSingleton(context)); + if(encodingArg) + encoding = encodingArg.stringValue(); + } + + Q_ASSERT(uri.isValid() && !uri.isRelative()); + return context->resourceLoader()->openUnparsedText(uri, encoding, context, this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qunparsedtextfn_p.h b/src/xmlpatterns/functions/qunparsedtextfn_p.h new file mode 100644 index 0000000..0661c27 --- /dev/null +++ b/src/xmlpatterns/functions/qunparsedtextfn_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_UnparsedTextFN_H +#define Patternist_UnparsedTextFN_H + +#include "qstaticbaseuricontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE +namespace QPatternist +{ + + /** + * @short Implements the function <tt>fn:unparsed-text()</tt>. + * + * @ingroup Patternist_functions + * @see <a href="http://www.w3.org/TR/xslt20/#unparsed-text">XSL + * Transformations (XSLT) Version 2.0, 16.2 unparsed-text</a> + * @author Frans Englich <fenglich@trolltech.com> + * @since 4.5 + */ + class UnparsedTextFN : public StaticBaseUriContainer + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qxpath10corefunctions.cpp b/src/xmlpatterns/functions/qxpath10corefunctions.cpp new file mode 100644 index 0000000..787eac0 --- /dev/null +++ b/src/xmlpatterns/functions/qxpath10corefunctions.cpp @@ -0,0 +1,300 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonnamespaces_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qpatternistlocale_p.h" +#include "qxmlname.h" + +/* Functions */ +#include "qaccessorfns_p.h" +#include "qaggregatefns_p.h" +#include "qbooleanfns_p.h" +#include "qcomparestringfns_p.h" +#include "qcontextfns_p.h" +#include "qnodefns_p.h" +#include "qnumericfns_p.h" +#include "qsequencefns_p.h" +#include "qsequencegeneratingfns_p.h" +#include "qstringvaluefns_p.h" +#include "qsubstringfns_p.h" + +#include "qxpath10corefunctions_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Expression::Ptr XPath10CoreFunctions::retrieveExpression(const QXmlName name, + const Expression::List &args, + const FunctionSignature::Ptr &sign) const +{ + Q_ASSERT(sign); + + Expression::Ptr fn; +#define testFN(ln, cname) else if(name.localName() == StandardLocalNames::ln) fn = Expression::Ptr(new cname()) + + if(false) /* Dummy for the macro handling. Will be optimized away anyway. */ + return Expression::Ptr(); + /* Alphabetic order. */ + testFN(boolean, BooleanFN); + testFN(ceiling, CeilingFN); + testFN(concat, ConcatFN); + testFN(contains, ContainsFN); + testFN(count, CountFN); + testFN(False, FalseFN); + testFN(floor, FloorFN); + testFN(id, IdFN); + testFN(lang, LangFN); + testFN(last, LastFN); + testFN(local_name, LocalNameFN); + testFN(name, NameFN); + testFN(namespace_uri, NamespaceURIFN); + testFN(normalize_space, NormalizeSpaceFN); + testFN(Not, NotFN); + testFN(number, NumberFN); + testFN(position, PositionFN); + testFN(round, RoundFN); + testFN(starts_with, StartsWithFN); + testFN(string, StringFN); + testFN(string_length, StringLengthFN); + testFN(substring, SubstringFN); + testFN(substring_after, SubstringAfterFN); + testFN(substring_before, SubstringBeforeFN); + testFN(sum, SumFN); + testFN(translate, TranslateFN); + testFN(True, TrueFN); +#undef testFN + + Q_ASSERT(fn); + fn->setOperands(args); + fn->as<FunctionCall>()->setSignature(sign); + + return fn; +} + +FunctionSignature::Ptr XPath10CoreFunctions::retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name) +{ + if(StandardNamespaces::fn != name.namespaceURI()) + return FunctionSignature::Ptr(); + + FunctionSignature::Ptr s(functionSignatures().value(name)); + + if(!s) + { + const QXmlName::LocalNameCode localName(name.localName()); + + /* Alphabetic order. */ + if(StandardLocalNames::boolean == localName) + { + s = addFunction(StandardLocalNames::boolean, 1, 1, CommonSequenceTypes::ExactlyOneBoolean); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::EBV); + } + else if(StandardLocalNames::ceiling == localName) + { + s = addFunction(StandardLocalNames::ceiling, 1, 1, CommonSequenceTypes::ZeroOrOneNumeric, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNumeric); + } + else if(StandardLocalNames::concat == localName) + { + s = addFunction(StandardLocalNames::concat, 2, FunctionSignature::UnlimitedArity, + CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneAtomicType); + s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneAtomicType); + } + else if(StandardLocalNames::contains == localName) + { + s = addFunction(StandardLocalNames::contains, 2, 3, CommonSequenceTypes::ExactlyOneBoolean, + Expression::LastOperandIsCollation); + s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::count == localName) + { + s = addFunction(StandardLocalNames::count, 1, 1, CommonSequenceTypes::ExactlyOneInteger, Expression::IDCountFN); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems); + } + else if(StandardLocalNames::False == localName) + { + s = addFunction(StandardLocalNames::False, 0, 0, CommonSequenceTypes::ExactlyOneBoolean); + } + else if(StandardLocalNames::floor == localName) + { + s = addFunction(StandardLocalNames::floor, 1, 1, CommonSequenceTypes::ZeroOrOneNumeric, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNumeric); + } + else if(StandardLocalNames::id == localName) + { + s = addFunction(StandardLocalNames::id, 1, 2, CommonSequenceTypes::ZeroOrMoreElements, + Expression::UseContextItem); + s->appendArgument(argument(np, "idrefs"), CommonSequenceTypes::ZeroOrMoreStrings); + s->appendArgument(argument(np, "node"), CommonSequenceTypes::ExactlyOneNode); + } + else if(StandardLocalNames::lang == localName) + { + s = addFunction(StandardLocalNames::lang, 1, 2, CommonSequenceTypes::ExactlyOneBoolean, + Expression::UseContextItem); + s->appendArgument(argument(np, "testLang"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "node"), CommonSequenceTypes::ExactlyOneNode); + } + else if(StandardLocalNames::last == localName) + { + s = addFunction(StandardLocalNames::last, 0, 0, CommonSequenceTypes::ExactlyOneInteger, + Expression::DisableElimination | Expression::RequiresFocus); + } + else if(StandardLocalNames::local_name == localName) + { + s = addFunction(StandardLocalNames::local_name, 0, 1, CommonSequenceTypes::ExactlyOneString, + Expression::UseContextItem); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode); + } + else if(StandardLocalNames::name == localName) + { + s = addFunction(StandardLocalNames::name, 0, 1, CommonSequenceTypes::ExactlyOneString, + Expression::UseContextItem); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode); + } + else if(StandardLocalNames::namespace_uri == localName) + { + s = addFunction(StandardLocalNames::namespace_uri, 0, 1, CommonSequenceTypes::ExactlyOneAnyURI, + Expression::UseContextItem); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode); + } + else if(StandardLocalNames::normalize_space == localName) + { + s = addFunction(StandardLocalNames::normalize_space, 0, 1, CommonSequenceTypes::ExactlyOneString, + Expression::UseContextItem); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString); + } + else if(StandardLocalNames::Not == localName) + { + s = addFunction(StandardLocalNames::Not, 1, 1, CommonSequenceTypes::ExactlyOneBoolean); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::EBV); + } + else if(StandardLocalNames::number == localName) + { + s = addFunction(StandardLocalNames::number, 0, 1, CommonSequenceTypes::ExactlyOneDouble, + Expression::UseContextItem); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneAtomicType); + } + else if(StandardLocalNames::position == localName) + { + s = addFunction(StandardLocalNames::position, 0, 0, CommonSequenceTypes::ExactlyOneInteger, + Expression::DisableElimination | Expression::RequiresFocus); + } + else if(StandardLocalNames::round == localName) + { + s = addFunction(StandardLocalNames::round, 1, 1, CommonSequenceTypes::ZeroOrOneNumeric, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNumeric); + } + else if(StandardLocalNames::starts_with == localName) + { + s = addFunction(StandardLocalNames::starts_with, 2, 3, CommonSequenceTypes::ExactlyOneBoolean, + Expression::LastOperandIsCollation); + s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::string == localName) + { + s = addFunction(StandardLocalNames::string, 0, 1, CommonSequenceTypes::ExactlyOneString, + Expression::UseContextItem); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneItem); + } + else if(StandardLocalNames::string_length == localName) + { + s = addFunction(StandardLocalNames::string_length, 0, 1, + CommonSequenceTypes::ExactlyOneInteger, + Expression::UseContextItem); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString); + } + else if(StandardLocalNames::substring == localName) + { + s = addFunction(StandardLocalNames::substring, 2, 3, CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "sourceString"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "startingLoc"), CommonSequenceTypes::ExactlyOneDouble); + s->appendArgument(argument(np, "length"), CommonSequenceTypes::ExactlyOneDouble); + } + else if(StandardLocalNames::substring_after == localName) + { + s = addFunction(StandardLocalNames::substring_after, 2, 3, CommonSequenceTypes::ExactlyOneString, + Expression::LastOperandIsCollation); + s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::substring_before == localName) + { + s = addFunction(StandardLocalNames::substring_before, 2, 3, CommonSequenceTypes::ExactlyOneString, + Expression::LastOperandIsCollation); + s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::sum == localName) + { + s = addFunction(StandardLocalNames::sum, 1, 2, CommonSequenceTypes::ZeroOrOneAtomicType); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreAtomicTypes); + s->appendArgument(argument(np, "zero"), CommonSequenceTypes::ZeroOrOneAtomicType); + } + else if(StandardLocalNames::translate == localName) + { + s = addFunction(StandardLocalNames::translate, 3, 3, CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "mapString"), CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "transString"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::True == localName) + { + s = addFunction(StandardLocalNames::True, 0, 0, CommonSequenceTypes::ExactlyOneBoolean); + } + } + + return s; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qxpath10corefunctions_p.h b/src/xmlpatterns/functions/qxpath10corefunctions_p.h new file mode 100644 index 0000000..3887495 --- /dev/null +++ b/src/xmlpatterns/functions/qxpath10corefunctions_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_XPath10CoreFunctions_H +#define Patternist_XPath10CoreFunctions_H + +#include "qabstractfunctionfactory_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Supplies the functions available in XPath 1.0. + * + * @ingroup Patternist_functions + * @see <a href="http://www.w3.org/TR/xpath.html#corelib">XML Path Language (XPath) + * Version 1.0, 4 Core Function Library</a> + * @see XPath20CoreFunctions + * @author Frans Englich <fenglich@trolltech.com> + */ + class XPath10CoreFunctions : public AbstractFunctionFactory + { + protected: + /** + * This function is responsible for creating the actual Expression, corresponding + * to @p localName and the function signature @p sign. It is called by + * createFunctionCall(), once it have been determined the function actually + * exists and have the correct arity. + */ + virtual Expression::Ptr retrieveExpression(const QXmlName name, + const Expression::List &args, + const FunctionSignature::Ptr &sign) const; + virtual FunctionSignature::Ptr retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qxpath20corefunctions.cpp b/src/xmlpatterns/functions/qxpath20corefunctions.cpp new file mode 100644 index 0000000..384a77c --- /dev/null +++ b/src/xmlpatterns/functions/qxpath20corefunctions.cpp @@ -0,0 +1,748 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qanyuri_p.h" +#include "qatomizer_p.h" +#include "qbuiltintypes_p.h" +#include "qcardinalityverifier_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qemptysequence_p.h" +#include "qcommonnamespaces_p.h" +#include "qxmlname.h" +#include "qatomicstring_p.h" + +/* Functions */ +#include "qaccessorfns_p.h" +#include "qaggregatefns_p.h" +#include "qassemblestringfns_p.h" +#include "qbooleanfns_p.h" +#include "qcomparestringfns_p.h" +#include "qcomparingaggregator_p.h" +#include "qcontextfns_p.h" +#include "qdatetimefn_p.h" +#include "qdatetimefns_p.h" +#include "qdeepequalfn_p.h" +#include "qerrorfn_p.h" +#include "qnodefns_p.h" +#include "qnumericfns_p.h" +#include "qpatternmatchingfns_p.h" +#include "qqnamefns_p.h" +#include "qresolveurifn_p.h" +#include "qsequencefns_p.h" +#include "qsequencegeneratingfns_p.h" +#include "qstringvaluefns_p.h" +#include "qsubstringfns_p.h" +#include "qtimezonefns_p.h" +#include "qtracefn_p.h" + +#include "qxpath20corefunctions_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Expression::Ptr XPath20CoreFunctions::retrieveExpression(const QXmlName name, + const Expression::List &args, + const FunctionSignature::Ptr &sign) const +{ + Q_ASSERT(sign); + + Expression::Ptr fn; +#define testFN(ln, cname) else if(name.localName() == StandardLocalNames::ln) fn = Expression::Ptr(new cname()) + + if(false) /* Dummy for the macro handling. Will be optimized away anyway. */ + return Expression::Ptr(); + /* Alphabetic order. */ + testFN(QName, QNameFN); + testFN(abs, AbsFN); + testFN(adjust_date_to_timezone, AdjustDateToTimezoneFN); + testFN(adjust_dateTime_to_timezone, AdjustDateTimeToTimezoneFN); + testFN(adjust_time_to_timezone, AdjustTimeToTimezoneFN); + testFN(avg, AvgFN); + testFN(base_uri, BaseURIFN); + testFN(codepoint_equal, CodepointEqualFN); + testFN(codepoints_to_string, CodepointsToStringFN); + testFN(collection, CollectionFN); + testFN(compare, CompareFN); + testFN(current_date, CurrentDateFN); + testFN(current_dateTime, CurrentDateTimeFN); + testFN(current_time, CurrentTimeFN); + testFN(dateTime, DateTimeFN); + testFN(day_from_date, DayFromAbstractDateTimeFN); + testFN(day_from_dateTime, DayFromAbstractDateTimeFN); + testFN(days_from_duration, DaysFromDurationFN); + testFN(deep_equal, DeepEqualFN); + testFN(default_collation, DefaultCollationFN); + testFN(distinct_values, DistinctValuesFN); + testFN(doc, DocFN); + testFN(doc_available, DocAvailableFN); + testFN(document_uri, DocumentURIFN); + testFN(empty, Existence<Expression::IDEmptyFN>); + testFN(encode_for_uri, EncodeForURIFN); + testFN(ends_with, EndsWithFN); + testFN(error, ErrorFN); + testFN(escape_html_uri, EscapeHtmlURIFN); + testFN(exists, Existence<Expression::IDExistsFN>); + testFN(hours_from_dateTime, HoursFromAbstractDateTimeFN); + testFN(hours_from_duration, HoursFromDurationFN); + testFN(hours_from_time, HoursFromAbstractDateTimeFN); + testFN(idref, IdrefFN); + testFN(implicit_timezone, ImplicitTimezoneFN); + testFN(in_scope_prefixes, InScopePrefixesFN); + testFN(index_of, IndexOfFN); + testFN(insert_before, InsertBeforeFN); + testFN(iri_to_uri, IriToURIFN); + testFN(local_name_from_QName, LocalNameFromQNameFN); + testFN(lower_case, LowerCaseFN); + testFN(matches, MatchesFN); + testFN(max, MaxFN); + testFN(min, MinFN); + testFN(minutes_from_dateTime, MinutesFromAbstractDateTimeFN); + testFN(minutes_from_duration, MinutesFromDurationFN); + testFN(minutes_from_time, MinutesFromAbstractDateTimeFN); + testFN(month_from_date, MonthFromAbstractDateTimeFN); + testFN(month_from_dateTime, MonthFromAbstractDateTimeFN); + testFN(months_from_duration, MonthsFromDurationFN); + testFN(namespace_uri_for_prefix, NamespaceURIForPrefixFN); + testFN(namespace_uri_from_QName, NamespaceURIFromQNameFN); + testFN(nilled, NilledFN); + testFN(node_name, NodeNameFN); + testFN(normalize_unicode, NormalizeUnicodeFN); + testFN(prefix_from_QName, PrefixFromQNameFN); + testFN(remove, RemoveFN); + testFN(replace, ReplaceFN); + testFN(resolve_QName, ResolveQNameFN); + testFN(resolve_uri, ResolveURIFN); + testFN(generic_string_join, StringJoinFN); + testFN(reverse, ReverseFN); + testFN(root, RootFN); + testFN(round_half_to_even, RoundHalfToEvenFN); + testFN(seconds_from_dateTime, SecondsFromAbstractDateTimeFN); + testFN(seconds_from_duration, SecondsFromDurationFN); + testFN(seconds_from_time, SecondsFromAbstractDateTimeFN); + testFN(static_base_uri, StaticBaseURIFN); + testFN(string_join, StringJoinFN); + testFN(string_to_codepoints, StringToCodepointsFN); + testFN(subsequence, SubsequenceFN); + testFN(timezone_from_date, TimezoneFromAbstractDateTimeFN); + testFN(timezone_from_dateTime, TimezoneFromAbstractDateTimeFN); + testFN(timezone_from_time, TimezoneFromAbstractDateTimeFN); + testFN(tokenize, TokenizeFN); + testFN(trace, TraceFN); + testFN(upper_case, UpperCaseFN); + testFN(year_from_date, YearFromAbstractDateTimeFN); + testFN(year_from_dateTime, YearFromAbstractDateTimeFN); + testFN(years_from_duration, YearsFromDurationFN); +#undef testFN + + if(fn) + { + fn->setOperands(args); + fn->as<FunctionCall>()->setSignature(sign); + } + else + { + /* Do the ones which are not FunctionCall sub-classes. The effect is + * that FunctionCall sub-classes has "automatic" type checking in the base + * class done from the background of their function signature, while + * these special classes are on their own, and must do it manually. */ + if(name.localName() == StandardLocalNames::data) + fn = Expression::Ptr(new Atomizer(args.first())); + else if(name.localName() == StandardLocalNames::zero_or_one) + fn = Expression::Ptr(new CardinalityVerifier(args.first(), Cardinality::zeroOrOne(), + ReportContext::FORG0003)); + else if(name.localName() == StandardLocalNames::one_or_more) + fn = Expression::Ptr(new CardinalityVerifier(args.first(), Cardinality::oneOrMore(), + ReportContext::FORG0004)); + else if(name.localName() == StandardLocalNames::exactly_one) + fn = Expression::Ptr(new CardinalityVerifier(args.first(), Cardinality::exactlyOne(), + ReportContext::FORG0005)); + else if(name.localName() == StandardLocalNames::unordered) + /* We don't make use of the unordered() function, so just pop in + * the arg. */ + fn = args.first(); + } + + return fn; +} + +FunctionSignature::Ptr XPath20CoreFunctions::retrieveFunctionSignature(const NamePool::Ptr &np, + const QXmlName name) +{ + if(StandardNamespaces::fn != name.namespaceURI() && name.namespaceURI() != StandardNamespaces::InternalXSLT) + return FunctionSignature::Ptr(); + + FunctionSignature::Ptr s(functionSignatures().value(name)); + + if(!s) + { + const QXmlName::LocalNameCode localName = name.localName(); + + /* Alphabetic order. */ + if(StandardLocalNames::QName == localName) + { + s = addFunction(StandardLocalNames::QName, 2, 2, CommonSequenceTypes::ExactlyOneQName); + s->appendArgument(argument(np, "paramURI"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "paramQName"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::abs == localName) + { + s = addFunction(StandardLocalNames::abs, 1, 1, CommonSequenceTypes::ZeroOrOneNumeric, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNumeric); + } + else if(StandardLocalNames::adjust_date_to_timezone == localName) + { + s = addFunction(StandardLocalNames::adjust_date_to_timezone, 1, 2, CommonSequenceTypes::ZeroOrOneDate, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDate); + s->appendArgument(argument(np, "timezone"), CommonSequenceTypes::ZeroOrOneDayTimeDuration); + } + else if(StandardLocalNames::adjust_dateTime_to_timezone == localName) + { + s = addFunction(StandardLocalNames::adjust_dateTime_to_timezone, 1, 2, CommonSequenceTypes::ZeroOrOneDateTime, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime); + s->appendArgument(argument(np, "timezone"), CommonSequenceTypes::ZeroOrOneDayTimeDuration); + } + else if(StandardLocalNames::adjust_time_to_timezone == localName) + { + s = addFunction(StandardLocalNames::adjust_time_to_timezone, 1, 2, CommonSequenceTypes::ZeroOrOneTime, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneTime); + s->appendArgument(argument(np, "timezone"), CommonSequenceTypes::ZeroOrOneDayTimeDuration); + } + else if(StandardLocalNames::avg == localName) + { + s = addFunction(StandardLocalNames::avg, 1, 1, CommonSequenceTypes::ZeroOrOneAtomicType, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreAtomicTypes); + } + else if(StandardLocalNames::base_uri == localName) + { + s = addFunction(StandardLocalNames::base_uri, 0, 1, CommonSequenceTypes::ZeroOrOneAnyURI, + Expression::UseContextItem); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode); + } + else if(StandardLocalNames::codepoint_equal == localName) + { + s = addFunction(StandardLocalNames::codepoint_equal, 2, 2, CommonSequenceTypes::ZeroOrOneBoolean); + s->appendArgument(argument(np, "comparand1"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "comparand2"), CommonSequenceTypes::ZeroOrOneString); + } + else if(StandardLocalNames::codepoints_to_string == localName) + { + s = addFunction(StandardLocalNames::codepoints_to_string, 1, 1, CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreIntegers); + } + else if(StandardLocalNames::collection == localName) + { + s = addFunction(StandardLocalNames::collection, 0, 1, CommonSequenceTypes::ZeroOrMoreNodes); + s->appendArgument(argument(np, "uri"), CommonSequenceTypes::ZeroOrOneString); + } + else if(StandardLocalNames::compare == localName) + { + s = addFunction(StandardLocalNames::compare, 2, 3, CommonSequenceTypes::ZeroOrOneInteger, + Expression::LastOperandIsCollation); + s->appendArgument(argument(np, "comparand1"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "comparand2"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::current_date == localName) + { + s = addFunction(StandardLocalNames::current_date, 0, 0, CommonSequenceTypes::ExactlyOneDate, + Expression::DisableElimination); + } + else if(StandardLocalNames::current_dateTime == localName) + { + s = addFunction(StandardLocalNames::current_dateTime, 0, 0, CommonSequenceTypes::ExactlyOneDateTime, + Expression::DisableElimination); + } + else if(StandardLocalNames::current_time == localName) + { + s = addFunction(StandardLocalNames::current_time, 0, 0, CommonSequenceTypes::ExactlyOneTime, + Expression::DisableElimination); + } + else if(StandardLocalNames::data == localName) + { + s = addFunction(StandardLocalNames::data, 1, 1, CommonSequenceTypes::ZeroOrMoreAtomicTypes); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems); + } + else if(StandardLocalNames::dateTime == localName) + { + s = addFunction(StandardLocalNames::dateTime, 2, 2, CommonSequenceTypes::ZeroOrOneDateTime); + s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneDate); + s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneTime); + } + else if(StandardLocalNames::day_from_date == localName) + { + s = addFunction(StandardLocalNames::day_from_date, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDate); + } + else if(StandardLocalNames::day_from_dateTime == localName) + { + s = addFunction(StandardLocalNames::day_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime); + } + else if(StandardLocalNames::days_from_duration == localName) + { + s = addFunction(StandardLocalNames::days_from_duration, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDuration); + } + else if(StandardLocalNames::deep_equal == localName) + { + s = addFunction(StandardLocalNames::deep_equal, 2, 3, CommonSequenceTypes::ExactlyOneBoolean, + Expression::LastOperandIsCollation); + s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrMoreItems); + s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrMoreItems); + s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::default_collation == localName) + { + s = addFunction(StandardLocalNames::default_collation, 0, 0, CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::distinct_values == localName) + { + s = addFunction(StandardLocalNames::distinct_values, 1, 2, CommonSequenceTypes::ZeroOrMoreAtomicTypes, + Expression::LastOperandIsCollation | + Expression::EmptynessFollowsChild | + Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreAtomicTypes); + s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::doc == localName) + { + s = addFunction(StandardLocalNames::doc, 1, 1, CommonSequenceTypes::ZeroOrOneDocumentNode, Expression::DisableElimination); + s->appendArgument(argument(np, "uri"), CommonSequenceTypes::ZeroOrOneString); + } + else if(StandardLocalNames::doc_available == localName) + { + s = addFunction(StandardLocalNames::doc_available, 1, 1, CommonSequenceTypes::ExactlyOneBoolean, Expression::DisableElimination); + s->appendArgument(argument(np, "uri"), CommonSequenceTypes::ZeroOrOneString); + } + else if(StandardLocalNames::document_uri == localName) + { + s = addFunction(StandardLocalNames::document_uri, 1, 1, CommonSequenceTypes::ZeroOrOneAnyURI); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode); + } + else if(StandardLocalNames::empty == localName) + { + s = addFunction(StandardLocalNames::empty, 1, 1, CommonSequenceTypes::ExactlyOneBoolean, Expression::IDEmptyFN); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems); + } + else if(StandardLocalNames::encode_for_uri == localName) + { + s = addFunction(StandardLocalNames::encode_for_uri, 1, 1, CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "uriPart"), CommonSequenceTypes::ZeroOrOneString); + } + else if(StandardLocalNames::ends_with == localName) + { + s = addFunction(StandardLocalNames::ends_with, 2, 3, CommonSequenceTypes::ExactlyOneBoolean, + Expression::LastOperandIsCollation); + s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::error == localName) + { + s = addFunction(StandardLocalNames::error, 0, 3, CommonSequenceTypes::None, + Expression::DisableElimination | Expression::DisableTypingDeduction); + s->appendArgument(argument(np, "error"), CommonSequenceTypes::ZeroOrOneQName); + s->appendArgument(argument(np, "description"), CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "errorObject"), CommonSequenceTypes::ZeroOrMoreItems); + } + else if(StandardLocalNames::escape_html_uri == localName) + { + s = addFunction(StandardLocalNames::escape_html_uri, 1, 1, CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "uri"), CommonSequenceTypes::ZeroOrOneString); + } + else if(StandardLocalNames::exactly_one == localName) + { + s = addFunction(StandardLocalNames::exactly_one, 1, 1, CommonSequenceTypes::ExactlyOneItem); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ExactlyOneItem); + } + else if(StandardLocalNames::exists == localName) + { + s = addFunction(StandardLocalNames::exists, 1, 1, CommonSequenceTypes::ExactlyOneBoolean, Expression::IDExistsFN); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems); + } + else if(StandardLocalNames::hours_from_dateTime == localName) + { + s = addFunction(StandardLocalNames::hours_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime); + } + else if(StandardLocalNames::hours_from_duration == localName) + { + s = addFunction(StandardLocalNames::hours_from_duration, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDuration); + } + else if(StandardLocalNames::hours_from_time == localName) + { + s = addFunction(StandardLocalNames::hours_from_time, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneTime); + } + else if(StandardLocalNames::idref == localName) + { + s = addFunction(StandardLocalNames::idref, 1, 2, CommonSequenceTypes::ZeroOrMoreElements, + Expression::UseContextItem); + s->appendArgument(argument(np, "idrefs"), CommonSequenceTypes::ZeroOrMoreStrings); + s->appendArgument(argument(np, "node"), CommonSequenceTypes::ExactlyOneNode); + } + else if(StandardLocalNames::implicit_timezone == localName) + { + s = addFunction(StandardLocalNames::implicit_timezone, 0, 0, CommonSequenceTypes::ExactlyOneDayTimeDuration, + Expression::DisableElimination); + } + else if(StandardLocalNames::in_scope_prefixes == localName) + { + s = addFunction(StandardLocalNames::in_scope_prefixes, 1, 1, CommonSequenceTypes::ZeroOrMoreStrings); + s->appendArgument(argument(np, "element"), CommonSequenceTypes::ExactlyOneElement); + } + else if(StandardLocalNames::index_of == localName) + { + s = addFunction(StandardLocalNames::index_of, 2, 3, CommonSequenceTypes::ZeroOrMoreIntegers, + Expression::LastOperandIsCollation); + s->appendArgument(argument(np, "seqParam"), CommonSequenceTypes::ZeroOrMoreAtomicTypes); + s->appendArgument(argument(np, "searchParam"), CommonSequenceTypes::ExactlyOneAtomicType); + s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::insert_before == localName) + { + s = addFunction(StandardLocalNames::insert_before, 3, 3, CommonSequenceTypes::ZeroOrMoreItems); + s->appendArgument(argument(np, "target"), CommonSequenceTypes::ZeroOrMoreItems); + s->appendArgument(argument(np, "position"), CommonSequenceTypes::ExactlyOneInteger); + s->appendArgument(argument(np, "insert"), CommonSequenceTypes::ZeroOrMoreItems); + } + else if(StandardLocalNames::iri_to_uri == localName) + { + s = addFunction(StandardLocalNames::iri_to_uri, 1, 1, CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "uri_part"), CommonSequenceTypes::ZeroOrOneString); + } + else if(StandardLocalNames::local_name_from_QName == localName) + { + s = addFunction(StandardLocalNames::local_name_from_QName, 1, 1, CommonSequenceTypes::ZeroOrOneNCName, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneQName); + } + else if(StandardLocalNames::lower_case == localName) + { + s = addFunction(StandardLocalNames::lower_case, 1, 1, CommonSequenceTypes::ExactlyOneString, + Expression::IDLowerCaseFN); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString); + } + else if(StandardLocalNames::matches == localName) + { + s = addFunction(StandardLocalNames::matches, 2, 3, CommonSequenceTypes::ExactlyOneBoolean); + s->appendArgument(argument(np, "input"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "pattern"), CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "flags"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::max == localName) + { + s = addFunction(StandardLocalNames::max, 1, 2, CommonSequenceTypes::ZeroOrOneAtomicType, + Expression::LastOperandIsCollation | + Expression::EmptynessFollowsChild | + Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreAtomicTypes); + s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::min == localName) + { + s = addFunction(StandardLocalNames::min, 1, 2, CommonSequenceTypes::ZeroOrOneAtomicType, + Expression::LastOperandIsCollation | + Expression::EmptynessFollowsChild | + Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreAtomicTypes); + s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::minutes_from_dateTime == localName) + { + s = addFunction(StandardLocalNames::minutes_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime); + } + else if(StandardLocalNames::minutes_from_duration == localName) + { + s = addFunction(StandardLocalNames::minutes_from_duration, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDuration); + } + else if(StandardLocalNames::minutes_from_time == localName) + { + s = addFunction(StandardLocalNames::minutes_from_time, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneTime); + } + else if(StandardLocalNames::month_from_date == localName) + { + s = addFunction(StandardLocalNames::month_from_date, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDate); + } + else if(StandardLocalNames::month_from_dateTime == localName) + { + s = addFunction(StandardLocalNames::month_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime); + } + else if(StandardLocalNames::months_from_duration == localName) + { + s = addFunction(StandardLocalNames::months_from_duration, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDuration); + } + else if(StandardLocalNames::namespace_uri_for_prefix == localName) + { + s = addFunction(StandardLocalNames::namespace_uri_for_prefix, 2, 2, CommonSequenceTypes::ZeroOrOneAnyURI); + s->appendArgument(argument(np, "prefix"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "element"), CommonSequenceTypes::ExactlyOneElement); + } + else if(StandardLocalNames::namespace_uri_from_QName == localName) + { + s = addFunction(StandardLocalNames::namespace_uri_from_QName, 1, 1, CommonSequenceTypes::ZeroOrOneAnyURI, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneQName); + } + else if(StandardLocalNames::nilled == localName) + { + s = addFunction(StandardLocalNames::nilled, 1, 1, CommonSequenceTypes::ZeroOrOneBoolean); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode); + } + else if(StandardLocalNames::node_name == localName) + { + s = addFunction(StandardLocalNames::node_name, 1, 1, CommonSequenceTypes::ZeroOrOneQName); + s->appendArgument(argument(np, "theNode"), CommonSequenceTypes::ZeroOrOneNode); + } + else if(StandardLocalNames::normalize_unicode == localName) + { + s = addFunction(StandardLocalNames::normalize_unicode, 1, 2, CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "normalizationForm"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::one_or_more == localName) + { + s = addFunction(StandardLocalNames::one_or_more, 1, 1, CommonSequenceTypes::OneOrMoreItems); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems); + } + else if(StandardLocalNames::prefix_from_QName == localName) + { + s = addFunction(StandardLocalNames::prefix_from_QName, 1, 1, CommonSequenceTypes::ZeroOrOneNCName, + Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneQName); + } + else if(StandardLocalNames::remove == localName) + { + s = addFunction(StandardLocalNames::remove, 2, 2, CommonSequenceTypes::ZeroOrMoreItems, + Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "target"), CommonSequenceTypes::ZeroOrMoreItems); + s->appendArgument(argument(np, "position"), CommonSequenceTypes::ExactlyOneInteger); + } + else if(StandardLocalNames::replace == localName) + { + s = addFunction(StandardLocalNames::replace, 3, 4, CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "input"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "pattern"), CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "replacement"), CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "flags"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::resolve_QName == localName) + { + s = addFunction(StandardLocalNames::resolve_QName, 2, 2, CommonSequenceTypes::ZeroOrOneQName, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "qname"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "element"), CommonSequenceTypes::ExactlyOneElement); + } + else if(StandardLocalNames::resolve_uri == localName) + { + s = addFunction(StandardLocalNames::resolve_uri, 1, 2, CommonSequenceTypes::ZeroOrOneAnyURI, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "relative"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "base"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::reverse == localName) + { + s = addFunction(StandardLocalNames::reverse, 1, 1, CommonSequenceTypes::ZeroOrMoreItems); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems); + } + else if(StandardLocalNames::root == localName) + { + s = addFunction(StandardLocalNames::root, 0, 1, CommonSequenceTypes::ZeroOrOneNode, + Expression::EmptynessFollowsChild | + Expression::RewriteToEmptyOnEmpty | + Expression::UseContextItem); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode); + } + else if(StandardLocalNames::round_half_to_even == localName) + { + s = addFunction(StandardLocalNames::round_half_to_even, 1, 2, CommonSequenceTypes::ZeroOrOneNumeric, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNumeric); + s->appendArgument(argument(np, "precision"), CommonSequenceTypes::ExactlyOneInteger); + } + else if(StandardLocalNames::seconds_from_dateTime == localName) + { + s = addFunction(StandardLocalNames::seconds_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneDecimal, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime); + } + else if(StandardLocalNames::seconds_from_duration == localName) + { + s = addFunction(StandardLocalNames::seconds_from_duration, 1, 1, CommonSequenceTypes::ZeroOrOneDecimal, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDuration); + } + else if(StandardLocalNames::seconds_from_time == localName) + { + s = addFunction(StandardLocalNames::seconds_from_time, 1, 1, CommonSequenceTypes::ZeroOrOneDecimal, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneTime); + } + else if(StandardLocalNames::static_base_uri == localName) + { + s = addFunction(StandardLocalNames::static_base_uri, 0, 0, CommonSequenceTypes::ExactlyOneAnyURI, Expression::EmptynessFollowsChild); + } + else if(StandardLocalNames::string_join == localName) + { + s = addFunction(StandardLocalNames::string_join, 2, 2, CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrMoreStrings); + s->appendArgument(argument(np, "separator"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::generic_string_join == localName) + { + s = addFunction(StandardLocalNames::generic_string_join, 2, 2, CommonSequenceTypes::ExactlyOneString, + Expression::IDIgnorableExpression, + Expression::Properties(), + StandardNamespaces::InternalXSLT); + s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrMoreAtomicTypes); + s->appendArgument(argument(np, "separator"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::string_to_codepoints == localName) + { + s = addFunction(StandardLocalNames::string_to_codepoints, 1, 1, CommonSequenceTypes::ZeroOrMoreIntegers); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString); + } + else if(StandardLocalNames::subsequence == localName) + { + s = addFunction(StandardLocalNames::subsequence, 2, 3, CommonSequenceTypes::ZeroOrMoreItems); + s->appendArgument(argument(np, "sourceSeq"), CommonSequenceTypes::ZeroOrMoreItems); + s->appendArgument(argument(np, "startingLoc"), CommonSequenceTypes::ExactlyOneDouble); + s->appendArgument(argument(np, "length"), CommonSequenceTypes::ExactlyOneDouble); + } + else if(StandardLocalNames::timezone_from_date == localName) + { + s = addFunction(StandardLocalNames::timezone_from_date, 1, 1, CommonSequenceTypes::ZeroOrOneDayTimeDuration, + Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDate); + } + else if(StandardLocalNames::timezone_from_dateTime == localName) + { + s = addFunction(StandardLocalNames::timezone_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneDayTimeDuration, + Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime); + } + else if(StandardLocalNames::timezone_from_time == localName) + { + s = addFunction(StandardLocalNames::timezone_from_time, 1, 1, CommonSequenceTypes::ZeroOrOneDayTimeDuration, + Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneTime); + } + else if(StandardLocalNames::tokenize == localName) + { + s = addFunction(StandardLocalNames::tokenize, 2, 3, CommonSequenceTypes::ZeroOrMoreStrings); + s->appendArgument(argument(np, "input"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "pattern"), CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "flags"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::trace == localName) + { + s = addFunction(StandardLocalNames::trace, 2, 2, CommonSequenceTypes::ZeroOrMoreItems, + Expression::DisableElimination); + s->appendArgument(argument(np, "value"), CommonSequenceTypes::ZeroOrMoreItems); + s->appendArgument(argument(np, "label"), CommonSequenceTypes::ExactlyOneString); + } + else if(StandardLocalNames::unordered == localName) + { + s = addFunction(StandardLocalNames::unordered, 1, 1, CommonSequenceTypes::ZeroOrMoreItems); + s->appendArgument(argument(np, "sourceSeq"), CommonSequenceTypes::ZeroOrMoreItems); + } + else if(StandardLocalNames::upper_case == localName) + { + s = addFunction(StandardLocalNames::upper_case, 1, 1, CommonSequenceTypes::ExactlyOneString, + Expression::IDUpperCaseFN); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString); + } + else if(StandardLocalNames::year_from_date == localName) + { + s = addFunction(StandardLocalNames::year_from_date, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDate); + } + else if(StandardLocalNames::year_from_dateTime == localName) + { + s = addFunction(StandardLocalNames::year_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime); + } + else if(StandardLocalNames::years_from_duration == localName) + { + s = addFunction(StandardLocalNames::years_from_duration, 1, 1, CommonSequenceTypes::ZeroOrOneInteger, + Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDuration); + } + else if(StandardLocalNames::zero_or_one == localName) + { + s = addFunction(StandardLocalNames::zero_or_one, 1, 1, CommonSequenceTypes::ZeroOrOneItem); + s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems); + } + } + + return s; +} + + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qxpath20corefunctions_p.h b/src/xmlpatterns/functions/qxpath20corefunctions_p.h new file mode 100644 index 0000000..fb5bee5 --- /dev/null +++ b/src/xmlpatterns/functions/qxpath20corefunctions_p.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_XPath20CoreFunctions_H +#define Patternist_XPath20CoreFunctions_H + +#include "qabstractfunctionfactory_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Handles the functions defines in XQuery 1.0 and XPath 2.0 + * Function and Operators, except those also available in XPath 1.0. + * + * All XPath 2.0 functions is the union of the functions available in XPath20CoreFunctions + * and XPath10CoreFunctions. One could therefore say that the name XPath20CoreFunctions is a + * bit misleading. + * + * @see XPath10CoreFunctions + * @see <a href ="http://www.w3.org/TR/xpath-functions/">XQuery 1.0 + * and XPath 2.0 Functions and Operators</a> + * @see <a href="http://www.w3.org/TR/xpath.html#corelib">XML Path Language (XPath) + * Version 1.0, 4 Core Function Library</a> + * @author Frans Englich <fenglich@trolltech.com> + * @ingroup Patternist_functions + */ + class XPath20CoreFunctions : public AbstractFunctionFactory + { + protected: + virtual Expression::Ptr retrieveExpression(const QXmlName name, + const Expression::List &args, + const FunctionSignature::Ptr &sign) const; + + virtual FunctionSignature::Ptr retrieveFunctionSignature(const NamePool::Ptr &np, + const QXmlName name); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/functions/qxslt20corefunctions.cpp b/src/xmlpatterns/functions/qxslt20corefunctions.cpp new file mode 100644 index 0000000..8e9ee17 --- /dev/null +++ b/src/xmlpatterns/functions/qxslt20corefunctions.cpp @@ -0,0 +1,175 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qanyuri_p.h" +#include "qcommonnamespaces_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcurrentfn_p.h" +#include "qdocumentfn_p.h" +#include "qelementavailablefn_p.h" +#include "qfunctionavailablefn_p.h" +#include "qgenerateidfn_p.h" +#include "qsystempropertyfn_p.h" +#include "qtypeavailablefn_p.h" +#include "qunparsedentitypublicidfn_p.h" +#include "qunparsedentityurifn_p.h" +#include "qunparsedtextavailablefn_p.h" +#include "qunparsedtextfn_p.h" + +#include "qxslt20corefunctions_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Expression::Ptr XSLT20CoreFunctions::retrieveExpression(const QXmlName lname, + const Expression::List &args, + const FunctionSignature::Ptr &sign) const +{ + Q_ASSERT(sign); + + Expression::Ptr fn; +#define testXSLTFN(ln, cname) else if(lname.localName() == StandardLocalNames::ln) fn = Expression::Ptr(new cname()) + + if(false) /* Dummy for the macro handling. Will be optimized away anyway. */ + return Expression::Ptr(); + /* Alphabetic order. */ + testXSLTFN(current, CurrentFN); + testXSLTFN(document, DocumentFN); + testXSLTFN(element_available, ElementAvailableFN); + testXSLTFN(function_available, FunctionAvailableFN); + testXSLTFN(generate_id, GenerateIDFN); + testXSLTFN(system_property, SystemPropertyFN); + testXSLTFN(type_available, TypeAvailableFN); + testXSLTFN(unparsed_entity_public_id, UnparsedEntityPublicIDFN); + testXSLTFN(unparsed_entity_uri, UnparsedEntityURIFN); + testXSLTFN(unparsed_text_available, UnparsedTextAvailableFN); + testXSLTFN(unparsed_text, UnparsedTextFN); +#undef testXSLTFN + + Q_ASSERT(fn); + fn->setOperands(args); + fn->as<FunctionCall>()->setSignature(sign); + + return fn; +} + +FunctionSignature::Ptr XSLT20CoreFunctions::retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name) +{ + if(StandardNamespaces::fn != name.namespaceURI()) + return FunctionSignature::Ptr(); + + FunctionSignature::Ptr s(functionSignatures().value(name)); + + if(!s) + { + /* Alphabetic order. */ + if(name.localName() == StandardLocalNames::element_available) + { + s = addFunction(StandardLocalNames::element_available, 1, 1, CommonSequenceTypes::ExactlyOneBoolean); + s->appendArgument(argument(np, "element-name"), CommonSequenceTypes::ExactlyOneString); + } + else if(name.localName() == StandardLocalNames::function_available) + { + s = addFunction(StandardLocalNames::function_available, 1, 2, CommonSequenceTypes::ExactlyOneBoolean); + s->appendArgument(argument(np, "function_name"), CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "arity"), CommonSequenceTypes::ExactlyOneInteger); + } + else if(name.localName() == StandardLocalNames::type_available) + { + s = addFunction(StandardLocalNames::type_available, 1, 1, CommonSequenceTypes::ExactlyOneBoolean); + s->appendArgument(argument(np, "type_name"), CommonSequenceTypes::ExactlyOneString); + } + else if(name.localName() == StandardLocalNames::system_property) + { + s = addFunction(StandardLocalNames::system_property, 1, 1, CommonSequenceTypes::ExactlyOneString); + s->appendArgument(argument(np, "property_name"), CommonSequenceTypes::ExactlyOneString); + } + else if(name.localName() == StandardLocalNames::generate_id) + { + s = addFunction(StandardLocalNames::generate_id, 0, 1, CommonSequenceTypes::ExactlyOneString, + Expression::UseContextItem); + s->appendArgument(argument(np, "node"), CommonSequenceTypes::ZeroOrOneNode); + } + else if(name.localName() == StandardLocalNames::unparsed_text) + { + s = addFunction(StandardLocalNames::unparsed_text, 1, 2, CommonSequenceTypes::ZeroOrOneString, + Expression::DisableElimination); + s->appendArgument(argument(np, "href"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "encoding"), CommonSequenceTypes::ExactlyOneString); + } + else if(name.localName() == StandardLocalNames::unparsed_text_available) + { + s = addFunction(StandardLocalNames::unparsed_text_available, 1, 2, CommonSequenceTypes::ExactlyOneBoolean, + Expression::DisableElimination); + s->appendArgument(argument(np, "href"), CommonSequenceTypes::ZeroOrOneString); + s->appendArgument(argument(np, "encoding"), CommonSequenceTypes::ZeroOrOneString); + } + else if(name.localName() == StandardLocalNames::current) + { + s = addFunction(StandardLocalNames::current, 0, 0, CommonSequenceTypes::ExactlyOneItem, + Expression::DisableElimination | Expression::RequiresCurrentItem); + } + else if(name.localName() == StandardLocalNames::document) + { + s = addFunction(StandardLocalNames::document, 1, 2, CommonSequenceTypes::OneOrMoreDocumentNodes, + Expression::DisableElimination); + s->appendArgument(argument(np, "uri-sequence"), CommonSequenceTypes::ZeroOrMoreStrings); + s->appendArgument(argument(np, "base-uri-node"), CommonSequenceTypes::ExactlyOneNode); + } + else if(name.localName() == StandardLocalNames::unparsed_entity_uri) + { + s = addFunction(StandardLocalNames::unparsed_entity_uri, 1, 1, CommonSequenceTypes::ExactlyOneAnyURI, + Expression::RequiresFocus | Expression::DisableElimination); + s->appendArgument(argument(np, "entity-name"), CommonSequenceTypes::ExactlyOneString); + } + else if(name.localName() == StandardLocalNames::unparsed_entity_public_id) + { + s = addFunction(StandardLocalNames::unparsed_entity_public_id, 1, 1, CommonSequenceTypes::ExactlyOneString, + Expression::RequiresFocus | Expression::DisableElimination); + s->appendArgument(argument(np, "entity-name"), CommonSequenceTypes::ExactlyOneString); + } + } + + return s; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/functions/qxslt20corefunctions_p.h b/src/xmlpatterns/functions/qxslt20corefunctions_p.h new file mode 100644 index 0000000..bbacf93 --- /dev/null +++ b/src/xmlpatterns/functions/qxslt20corefunctions_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_XSLT20CoreFunctions_H +#define Patternist_XSLT20CoreFunctions_H + +#include "qabstractfunctionfactory_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Handles the functions defines in XSL-T 2.0, except those also available in XPath 2.0. + * + * @note XPath20CoreFunctions inherits from XPath10CoreFunctions only for implementation + * reasons, it does not supply the functions in the XPath10CoreFunctions factory. + * + * @see <a href ="http://www.w3.org/TR/xpath-functions/">XQuery 1.0 + * and XPath 2.0 Functions and Operators</a> + * @see <a href="http://www.w3.org/TR/xpath.html#corelib">XML Path Language (XPath) + * Version 1.0, 4 Core Function Library</a> + * @author Frans Englich <fenglich@trolltech.com> + * @ingroup Patternist_functions + * @since 4.5 + */ + class XSLT20CoreFunctions : public AbstractFunctionFactory + { + protected: + virtual Expression::Ptr retrieveExpression(const QXmlName name, + const Expression::List &args, + const FunctionSignature::Ptr &sign) const; + + virtual FunctionSignature::Ptr retrieveFunctionSignature(const NamePool::Ptr &np, + const QXmlName name); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif |